<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>极客园M端</title>
    <meta name="generator" content="VuePress 1.8.2">
    
    <meta name="description" content="极客园-开发文档">
    
    <link rel="preload" href="/document/assets/css/0.styles.c9fde802.css" as="style"><link rel="preload" href="/document/assets/js/app.9911b446.js" as="script"><link rel="preload" href="/document/assets/js/3.5cec4c48.js" as="script"><link rel="preload" href="/document/assets/js/4.9359f99f.js" as="script"><link rel="prefetch" href="/document/assets/js/1.bb7b219c.js"><link rel="prefetch" href="/document/assets/js/10.5de95cfc.js"><link rel="prefetch" href="/document/assets/js/11.a0e28b35.js"><link rel="prefetch" href="/document/assets/js/5.3db35feb.js"><link rel="prefetch" href="/document/assets/js/6.015274ee.js"><link rel="prefetch" href="/document/assets/js/7.6b4f86a1.js"><link rel="prefetch" href="/document/assets/js/8.4cafca16.js"><link rel="prefetch" href="/document/assets/js/9.e310b536.js">
    <link rel="stylesheet" href="/document/assets/css/0.styles.c9fde802.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/document/" class="home-link router-link-active"><img src="/document/hero.png" alt="" class="logo"> <!----></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/document/guide/01-pc.html" class="nav-link">
  PC端项目
</a></div><div class="nav-item"><a href="/document/guide/02-vuex.html" class="nav-link">
  Vuex学习
</a></div><div class="nav-item"><a href="/document/guide/03-mobile.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  M端项目
</a></div> <a href="https://gitee.com/zhoushugang/" target="_blank" rel="noopener noreferrer" class="repo-link">
    Gitee
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/document/guide/01-pc.html" class="nav-link">
  PC端项目
</a></div><div class="nav-item"><a href="/document/guide/02-vuex.html" class="nav-link">
  Vuex学习
</a></div><div class="nav-item"><a href="/document/guide/03-mobile.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  M端项目
</a></div> <a href="https://gitee.com/zhoushugang/" target="_blank" rel="noopener noreferrer" class="repo-link">
    Gitee
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>极客园M端</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/document/guide/03-mobile.html#第一章-项目起步" class="sidebar-link">第一章：项目起步</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-项目介绍" class="sidebar-link">01-项目介绍</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-使用技术" class="sidebar-link">02-使用技术</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-创建项目" class="sidebar-link">03-创建项目</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-调整目录" class="sidebar-link">04-调整目录</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第二章-项目架构" class="sidebar-link">第二章：项目架构</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-引入vant" class="sidebar-link">01-引入vant</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-适配单位" class="sidebar-link">02-适配单位</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-进行适配" class="sidebar-link">03-进行适配</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-约定路由" class="sidebar-link">04-约定路由</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-命名视图-概念" class="sidebar-link">05-命名视图-概念</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_06-命名视图-应用" class="sidebar-link">06-命名视图-应用</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_07-实现tab栏" class="sidebar-link">07-实现tab栏</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_08-字体图标" class="sidebar-link">08-字体图标</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_09-图标组件" class="sidebar-link">09-图标组件</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_10-vue插件" class="sidebar-link">10-Vue插件</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_11-改造底部tab" class="sidebar-link">11-改造底部Tab</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_12-less全局变量" class="sidebar-link">12-Less全局变量</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_13-vuex管理状态" class="sidebar-link">13-Vuex管理状态</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_14-请求工具-基础" class="sidebar-link">14-请求工具-基础</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_15-请求工具-赋能" class="sidebar-link">15-请求工具-赋能</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_16-await异常处理" class="sidebar-link">16-await异常处理</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_17-接口api函数" class="sidebar-link">17-接口API函数</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第三章-登录模块" class="sidebar-link">第三章：登录模块</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-登录-导航守卫" class="sidebar-link">01-登录-导航守卫</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-登录-组件布局" class="sidebar-link">02-登录-组件布局</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-登录-表单校验" class="sidebar-link">03-登录-表单校验</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-登录-默认登录" class="sidebar-link">04-登录-默认登录</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-登录-短信登录" class="sidebar-link">05-登录-短信登录</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第四章-首页模块" class="sidebar-link">第四章：首页模块</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-首页-频道展示" class="sidebar-link">01-首页-频道展示</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-首页-文章组件" class="sidebar-link">02-首页-文章组件</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-首页-上拉加载" class="sidebar-link">03-首页-上拉加载</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-首页-下拉刷新" class="sidebar-link">04-首页-下拉刷新</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-首页-接入数据" class="sidebar-link">05-首页-接入数据</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_06-首页-处理时间" class="sidebar-link">06-首页-处理时间</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_07-首页-组件缓存" class="sidebar-link">07-首页-组件缓存</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_08-首页-阅读位置" class="sidebar-link">08-首页-阅读位置</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第五章-频道管理" class="sidebar-link">第五章：频道管理</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-频道-组件准备" class="sidebar-link">01-频道-组件准备</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-频道-组件布局" class="sidebar-link">02-频道-组件布局</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-频道-渲染我的频道" class="sidebar-link">03-频道-渲染我的频道</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-频道-渲染可选频道" class="sidebar-link">04-频道-渲染可选频道</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-频道-点击进入频道" class="sidebar-link">05-频道-点击进入频道</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_06-频道-支持本地操作" class="sidebar-link">06-频道-支持本地操作</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_07-频道-添加" class="sidebar-link">07-频道-添加</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_08-频道-切换编辑" class="sidebar-link">08-频道-切换编辑</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_09-频道-删除" class="sidebar-link">09-频道-删除</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第六章-文章详情" class="sidebar-link">第六章：文章详情</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-文章详情-顶部导航" class="sidebar-link">01-文章详情-顶部导航</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-文章详情-主体内容" class="sidebar-link">02-文章详情-主体内容</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-文章详情-渲染页面" class="sidebar-link">03-文章详情-渲染页面</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-文章详情-导航交互" class="sidebar-link">04-文章详情-导航交互</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-文章详情-关注作者" class="sidebar-link">05-文章详情-关注作者</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_06-文章详情-骨架效果" class="sidebar-link">06-文章详情-骨架效果</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_07-文章详情-代码高亮" class="sidebar-link">07-文章详情-代码高亮</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第七章-评论回复" class="sidebar-link">第七章：评论回复</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-文章评论-组件布局" class="sidebar-link">01-文章评论-组件布局</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-文章评论-渲染列表" class="sidebar-link">02-文章评论-渲染列表</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-文章评论-底部工具" class="sidebar-link">03-文章评论-底部工具</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-文章评论-传送功能" class="sidebar-link">04-文章评论-传送功能</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-文章评论-点赞" class="sidebar-link">05-文章评论-点赞</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_06-文章评论-收藏" class="sidebar-link">06-文章评论-收藏</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_07-评论回复-回复弹层" class="sidebar-link">07-评论回复-回复弹层</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_08-评论回复-列表渲染" class="sidebar-link">08-评论回复-列表渲染</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_09-填写文章评论" class="sidebar-link">09-填写文章评论</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_10-填写评论回复" class="sidebar-link">10-填写评论回复</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第八章-个人中心" class="sidebar-link">第八章：个人中心</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-个人中心-基础布局" class="sidebar-link">01-个人中心-基础布局</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-个人中心-渲染页面" class="sidebar-link">02-个人中心-渲染页面</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-编辑资料-页面布局" class="sidebar-link">03-编辑资料-页面布局</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_04-编辑资料-回显数据" class="sidebar-link">04-编辑资料-回显数据</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_05-编辑资料-退出登录" class="sidebar-link">05-编辑资料-退出登录</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_06-编辑资料-修改头像" class="sidebar-link">06-编辑资料-修改头像</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_07-编辑资料-修改昵称" class="sidebar-link">07-编辑资料-修改昵称</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_08-编辑资料-修改性别" class="sidebar-link">08-编辑资料-修改性别</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_09-编辑资料-修改生日" class="sidebar-link">09-编辑资料-修改生日</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_10-小智同学-基础布局" class="sidebar-link">10-小智同学-基础布局</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_11-小智同学-认识websocket" class="sidebar-link">11-小智同学-认识websocket</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_12-小智同学-完成聊天" class="sidebar-link">12-小智同学-完成聊天</a></li></ul></li><li><a href="/document/guide/03-mobile.html#第九章-项目收尾" class="sidebar-link">第九章：项目收尾</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_01-刷新token" class="sidebar-link">01-刷新token</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_02-打包部署" class="sidebar-link">02-打包部署</a></li><li class="sidebar-sub-header"><a href="/document/guide/03-mobile.html#_03-项目总结" class="sidebar-link">03-项目总结</a></li></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="极客园m端"><a href="#极客园m端" class="header-anchor">#</a> 极客园M端</h1> <h2 id="第一章-项目起步"><a href="#第一章-项目起步" class="header-anchor">#</a> 第一章：项目起步</h2> <h3 id="_01-项目介绍"><a href="#_01-项目介绍" class="header-anchor">#</a> 01-项目介绍</h3> <blockquote><p>目标：了解项目背景，了解项目功能。</p></blockquote> <p>项目背景：</p> <ul><li>它对标 CSDN 博客园 等竞品，致力成为全球知名的IT技术交流平台，它包含 技术文章，问答内容，视频解答 的专业IT资讯平台，它提供原创，优质，完整内容的专业IT社区。它是 <code>极客园</code> IT资讯社区。</li></ul> <p>项目功能：</p> <ul><li><code>极客园-个人端M</code> 是一款移动web应用。</li> <li>主要功能有：
<ul><li>首页-文章频道，文章列表，更多操作</li> <li>详情-文章详情，文章评论，评论回复，点赞，收藏，关注</li> <li>登录-短信登录</li> <li>个人-信息展示，信息编辑</li></ul></li></ul> <p>项目物料：http://geek.itheima.net</p> <p><strong>总结：</strong> 我们知道项目的大致功能即可。</p> <h3 id="_02-使用技术"><a href="#_02-使用技术" class="header-anchor">#</a> 02-使用技术</h3> <blockquote><p>目标：了解使用技术</p></blockquote> <p>开发依赖大致如下：</p> <ul><li>基础环境：<code>nodejs12+</code> <code>vscode</code> <code>vuecli4.x</code></li> <li>配套工具：<code>eslint</code> <code>babel</code> <code>less</code></li> <li>使用技术：<code>vue2.6.12</code> <code>vue-router</code> <code>vue-vuex</code> <code>vant</code> <code>iconfont</code> <code>dayjs</code> <code>socket.io-client</code> <code>postcss-px-to-viewport</code></li></ul> <p>项目中的解决方案：</p> <ul><li>使用vue-cli创建vue单页应用解决方案</li> <li>使用vue-router实现前端路由解决方案</li> <li>使用vue-vuex实现状态管理解决方案</li> <li>使用vant快速搭建移动界面解决方案</li> <li>使用json-bigint处理最大安全整数解决方案</li> <li>使用iconfont实现前端多色字体图标解决方案</li> <li>使用dayjs处理相对时间计算解决方案</li> <li>使用soket.io实现即时通讯解决方案</li> <li>使用postcss-px-to-viewport 实现移动端适配解决方</li></ul> <p><strong>总结：</strong> 我们大概知道用了那些东西即可。</p> <h3 id="_03-创建项目"><a href="#_03-创建项目" class="header-anchor">#</a> 03-创建项目</h3> <blockquote><p>目标：知道如何使用vue-cli创建项目</p></blockquote> <p>大致步骤：</p> <ul><li>在某个目录打开命令行工具输入创建项目的命令</li> <li>安装项目需求选择具体的工具，然后等待创建吧</li> <li>最后进入创建好的项目，启动项目即可</li></ul> <p>具体如下：</p> <ul><li>执行创建命令</li></ul> <div class="language-bash extra-class"><pre class="language-bash"><code>vue create geek-client-mobile
</code></pre></div><ul><li>选中自定义创建</li></ul> <p><img src="" alt="1622440144872"></p> <ul><li>选择Vue版本，依赖Babel降级ES6语法，依赖vue-router，依赖vuex，使用css预处理器，使用代码风格校验。</li></ul> <p><img src="" alt="1622440310596"></p> <ul><li>选择vue2.0版本</li></ul> <p><img src="" alt="1622440660281"></p> <ul><li>是否使用历史模式API，输入 n</li></ul> <p><img src="" alt="1622440752792"></p> <ul><li>选择less这种css预处理器</li></ul> <p><img src="" alt="1622440811661"></p> <ul><li>选择 通用语法风格配置</li></ul> <p><img src="" alt="1622440877508"></p> <ul><li>语法风格校验的时机，保存代码校验，提交代码校验且自动修复。</li></ul> <p><img src="/document/assets/img/1622441060425.952868fa.png" alt="1622441060425"></p> <ul><li>选择使用不同的配置文件对于所依赖工具</li></ul> <p><img src="/document/assets/img/1622441142876.091cead7.png" alt="1622441142876"></p> <ul><li>是否记录此次操作记录，输入 n</li></ul> <p><img src="" alt="1622441203780"></p> <ul><li>最后等待安装即可，安装完毕进入项目目录，执行 <code>npm run serve</code> 即可启动项目。</li></ul> <p><img src="" alt="1622443003736"></p> <p><strong>总结：</strong> 我们可以使用vuecli根据自己项目需求创建合适的项目。</p> <h3 id="_04-调整目录"><a href="#_04-调整目录" class="header-anchor">#</a> 04-调整目录</h3> <blockquote><p>目标：根据项目功能调整下目录结构</p></blockquote> <p>大致步骤：</p> <ul><li>配置文件解释说明</li> <li>调整src下目录结构</li></ul> <p>落地内容：</p> <ul><li>根目录和配置文件。都是自动生成的，了解作用即可</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>├─node_modules
├─public
├─src
├─.browserslistrc     # 适配浏览器列表
├─.editorconfig       # 提供给编辑器的配置
├─.eslintrc.js        # eslint代码风格配置
├─.gitignore          # git忽略文件配置
├─.babel.config.js    # babelES降级配置
├─package-lock.json   # 包下载版本说明文件
├─package.json        # 项目包说明文件
├─postcss.config.js   # postcss，css预处理器后处理器配置
├─README.md           # 说明MD文件
└─vue.config.js       # vue-cli的配置文件
</code></pre></div><ul><li>src 目录结构如下，仅供参考 （分模块的思维才重要）</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>├─api              # 接口函数
├─assets           # 项目资源
│  ├─images          # 图片 
│  └─styles          # less代码
├─components       # 全局组件，通用组件
├─router           # 路由
├─store            # 状态
├─utils            # 工具
└─views            # 路由组件（页面）
    ├─article        # 文章详情
    ├─home           # 首页
    ├─question       # 问答
    ├─user           # 用户模块
    └─video          # 视频
</code></pre></div><p><strong>总结：</strong> 做好开发前的准备，调整下项目结构。</p> <h2 id="第二章-项目架构"><a href="#第二章-项目架构" class="header-anchor">#</a> 第二章：项目架构</h2> <h3 id="_01-引入vant"><a href="#_01-引入vant" class="header-anchor">#</a> 01-引入vant</h3> <blockquote><p>目的：在项目中引入Vant组件库</p></blockquote> <p>大致步骤：</p> <ul><li>从官方了解引入Vant的几种方式 	<a href="https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart#yin-ru-zu-jian" target="_blank" rel="noopener noreferrer">引入vant方式<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> <ul><li>自动按需（推荐）- 打包体积小</li> <li>手动按需</li> <li>全部引入</li></ul></li> <li>我们采用 <strong>全部引入</strong> 方式
<ul><li>开发过程中使用方便，一次引入全局使用。</li> <li>后续做打包优化可以降低打包体积。</li></ul></li></ul> <p>落地代码：</p> <ul><li>安装</li></ul> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">npm</span> i vant
</code></pre></div><ul><li>引入 <code>main.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> Vant <span class="token keyword">from</span> <span class="token string">'vant'</span>
<span class="token keyword">import</span> <span class="token string">'vant/lib/index.css'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Vant<span class="token punctuation">)</span>
</code></pre></div><ul><li>测试  <code>App.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>primary<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>按钮<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-button</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><img src="" alt="1622513783623"></p> <p><strong>总结：</strong> 如果后续不做打包优化 <code>自动按需引入</code> 推荐，但是我们为了开发方便后续也会做打包优化使用 <code>全部引入</code> 方式。</p> <h3 id="_02-适配单位"><a href="#_02-适配单位" class="header-anchor">#</a> 02-适配单位</h3> <blockquote><p>目标：了解移动端适配方案，实现这些适配方案用到的尺寸单位。</p></blockquote> <p>大致步骤：</p> <ul><li>回忆下移动端<strong>等比例</strong>适配的单位，rem 或者 vw+vh</li> <li>在项目中使用 <code>vw</code> 来演示下适配的过程</li> <li>总结 <code>vw</code> 单位在做适配的方法</li></ul> <p>落地过程：</p> <ul><li>rem适配，vw适配</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>// 目标：等比例适配
// 1. iphone6  375px 盒子 100*100 
// 2. iphone6 plus  414px 盒子  110.4*110.4

// rem适配
// 1. iphone6  html===&gt;font-size:37.5px
// 2. iphone6 plus  html===&gt;font-size:41.4px
// 3. height:2.666rem; width:2.666rem;

// vw适配
// 1. height: 26.667vw; width: 26.667vw;
</code></pre></div><ul><li>演示 vw 效果</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>box<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">.box</span> <span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 26.66667vw<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 26.66667vw<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>总结下方案，设备宽度是 <code>375px</code> 那么  <code>1vw === 3.75px</code> ，需要将px单位换成vw即可。</li></ul> <p><strong>总结：</strong> 知道如果使用vw换算px单位，实现适配效果。但是手动换算效率太低，下一节来讲如果进行自动适配。</p> <h3 id="_03-进行适配"><a href="#_03-进行适配" class="header-anchor">#</a> 03-进行适配</h3> <blockquote><p>目标：在项目中加入vw的适配方案</p></blockquote> <p>大致步骤：</p> <ul><li>安装 postcss-px-to-viewport 插件</li> <li>新建一个 postcss.config.js 的配置文件</li> <li>添加插件配置 参考 <a href="https://vant-contrib.gitee.io/vant/#/zh-CN/advanced-usage#liu-lan-qi-gua-pei" target="_blank" rel="noopener noreferrer">浏览器适配<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <p>落地代码：</p> <ul><li>安装</li></ul> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">npm</span> <span class="token function">install</span> postcss-px-to-viewport --save-dev
</code></pre></div><ul><li>配置 <code>postcss.config.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  plugins<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token string">'postcss-px-to-viewport'</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      viewportWidth<span class="token operator">:</span> <span class="token number">375</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>注意，该插件对行内样式无效，建议样式通过类来定义。</li> <li>postcss 可以认为是后处理器，对css代码做后续的处理 （转单位，加私有前缀..）</li></ul> <p><strong>总结：</strong> 通过postcss-px-to-viewport插件解决移动端适配。</p> <h3 id="_04-约定路由"><a href="#_04-约定路由" class="header-anchor">#</a> 04-约定路由</h3> <blockquote><p>目标：约定好项目的路由设计</p></blockquote> <p>大致步骤：</p> <ul><li>先了解各个页面布局的基本构成</li> <li>再约定好路径和组件的映射关系</li></ul> <p>落地规则：</p> <table><thead><tr><th>路径</th> <th>组件</th> <th>功能</th></tr></thead> <tbody><tr><td>/</td> <td>Home+Tabbar</td> <td>首页</td></tr> <tr><td>/question</td> <td>Question+Tabbar</td> <td>问答</td></tr> <tr><td>/video</td> <td>Video+Tabbar</td> <td>视频</td></tr> <tr><td>/user</td> <td>User+Tabbar</td> <td>用户</td></tr> <tr><td>/user/profile</td> <td>UserProfile</td> <td>用户资料</td></tr> <tr><td>/user/chat</td> <td>UserChat</td> <td>小智同学</td></tr> <tr><td>/article</td> <td>Article</td> <td>文章详情</td></tr></tbody></table> <p><strong>总结：</strong> 全部采用一级路由来实现，不使用嵌套路由。（方便后续做组件缓存）</p> <h3 id="_05-命名视图-概念"><a href="#_05-命名视图-概念" class="header-anchor">#</a> 05-命名视图-概念</h3> <blockquote><p>目标：在不使用嵌套路由情况下，如何实现共同布局的复用。</p></blockquote> <p>官方话术： 有时候想同时 (同级) 展示多个视图，而不是嵌套展示，例如创建一个布局，有 <code>sidebar</code> (侧导航) 和 <code>main</code> (主内容) 两个视图，这个时候命名视图就派上用场了。<a href="https://router.vuejs.org/zh/guide/essentials/named-views.html#%E5%B5%8C%E5%A5%97%E5%91%BD%E5%90%8D%E8%A7%86%E5%9B%BE" target="_blank" rel="noopener noreferrer">参考地址<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>学习步骤：</p> <ul><li>什么是命名视图？
<ul><li>router-view组件有name属性，默认是default，可以指定名称。</li></ul></li> <li>使用场景在哪里？
<ul><li>一个路由规则，可以通过命名视图，指定多个组件，组件是同级的，而不是嵌套关系。</li></ul></li></ul> <p>落地分析：</p> <ul><li>嵌套视图：</li></ul> <p><img src="/document/assets/img/1622534525175.7496e8fa.png" alt="1622534525175"></p> <ul><li>命名视图：</li></ul> <p><img src="/document/assets/img/1622534918577.cb3cf2aa.png" alt="1622534918577"></p> <p><strong>总结：</strong> 在不使用嵌套视图情况下，可以使用命名视图来复用公用的布局内容。</p> <h3 id="_06-命名视图-应用"><a href="#_06-命名视图-应用" class="header-anchor">#</a> 06-命名视图-应用</h3> <blockquote><p>目标：使用命名视图完成项目路由的基本实现。</p></blockquote> <p>大致步骤：</p> <ul><li>定义一个tabbar组件</li> <li>定义 首页 问答 视频 用户 文章详情 等组件</li> <li>使用定义路由规则，使用命名视图，组织页面。</li></ul> <p>落的代码：</p> <p><code>src/components/app-tabbar.vue</code>  底部tab切换组件</p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>app-tabbar<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>tab<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'AppTabbar'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><code>src/views</code>  中 首页 问答 视频 用户 文章详情 等组件</p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>home-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>首页<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'HomePage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>question-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>问答<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'QuestionPage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>文章详情<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticlePage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>用户<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserPage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>video-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>视频<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'VideoPage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>

</code></pre></div><p><code>src/router/index.js</code> 路由规则</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> VueRouter <span class="token keyword">from</span> <span class="token string">'vue-router'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>VueRouter<span class="token punctuation">)</span>

<span class="token comment">// 路由懒加载方式</span>
<span class="token keyword">const</span> <span class="token function-variable function">Tabbar</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/components/app-tabbar.vue'</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">Home</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/views/home'</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">Question</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/views/question'</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">Video</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/views/video'</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">User</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/views/user'</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">Artcile</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/views/article'</span><span class="token punctuation">)</span>

<span class="token keyword">const</span> routes <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token comment">// 路由规则</span>
  <span class="token punctuation">{</span> path<span class="token operator">:</span> <span class="token string">'/'</span><span class="token punctuation">,</span> components<span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token keyword">default</span><span class="token operator">:</span> Home<span class="token punctuation">,</span> tabbar<span class="token operator">:</span> Tabbar <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> path<span class="token operator">:</span> <span class="token string">'/question'</span><span class="token punctuation">,</span> components<span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token keyword">default</span><span class="token operator">:</span> Question<span class="token punctuation">,</span> tabbar<span class="token operator">:</span> Tabbar <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> path<span class="token operator">:</span> <span class="token string">'/video'</span><span class="token punctuation">,</span> components<span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token keyword">default</span><span class="token operator">:</span> Video<span class="token punctuation">,</span> tabbar<span class="token operator">:</span> Tabbar <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> path<span class="token operator">:</span> <span class="token string">'/user'</span><span class="token punctuation">,</span> components<span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token keyword">default</span><span class="token operator">:</span> User<span class="token punctuation">,</span> tabbar<span class="token operator">:</span> Tabbar <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> path<span class="token operator">:</span> <span class="token string">'/article'</span><span class="token punctuation">,</span> component<span class="token operator">:</span> Artcile <span class="token punctuation">}</span>
<span class="token punctuation">]</span>

<span class="token keyword">const</span> router <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">VueRouter</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  routes
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> router

</code></pre></div><p><code>App.vue</code>  组织视图</p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>app<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>RouterView</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>body<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>RouterView</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>tabbar<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">#app</span> <span class="token punctuation">{</span>
  <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
  <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token selector">;
  .body</span> <span class="token punctuation">{</span>
    <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span> 
    <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>  
  <span class="token punctuation">}</span>
  <span class="token selector">.footer</span> <span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong> 可以使用命名视图再一层路由视图情况下，复用tabbar组件。</p> <h3 id="_07-实现tab栏"><a href="#_07-实现tab栏" class="header-anchor">#</a> 07-实现tab栏</h3> <blockquote><p>目标：使用vant的tabbar组件完成底部tab栏</p></blockquote> <p>大致步骤：</p> <ul><li>先去vant阅读下tabbar组件的模板代码</li> <li>再在app-tabbar.vue组件使用基础用法</li> <li>开启路由功能，指定跳转地址，更改文字。</li></ul> <p>落的代码：</p> <p><code>src/components/app-tabbar.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar</span> <span class="token attr-name">route</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>home-o<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>首页<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/question<span class="token punctuation">&quot;</span></span> <span class="token attr-name">icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>search<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>问答<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/video<span class="token punctuation">&quot;</span></span> <span class="token attr-name">icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>friends-o<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>视频<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/user<span class="token punctuation">&quot;</span></span> <span class="token attr-name">icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>setting-o<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>我的<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'AppTabbar'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong> van-tabbar的route是开启路由，van-tabbar-item的to属性是指定跳转地址。图标稍后处理。</p> <h3 id="_08-字体图标"><a href="#_08-字体图标" class="header-anchor">#</a> 08-字体图标</h3> <blockquote><p>目标：掌握如何使用svg的字体图标库iconfont</p></blockquote> <p>大致步骤：</p> <ul><li>在iconfont.com上生成字体图标的js文件</li> <li>在public下index.html头部引入该文件</li> <li>使用固定的svg语法来使用图标</li></ul> <p>落地代码：</p> <ul><li>第一步：在public下index.html头部引入该文件</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//at.alicdn.com/t/font_2496877_pghtj7rdgrh.js</span>
</code></pre></div><ul><li>第二步：组件中需要加入通用css代码</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>style type<span class="token operator">=</span><span class="token string">&quot;text/css&quot;</span><span class="token operator">&gt;</span>
    <span class="token punctuation">.</span>icon <span class="token punctuation">{</span>
       width<span class="token operator">:</span> <span class="token number">1</span>em<span class="token punctuation">;</span> 
       height<span class="token operator">:</span> <span class="token number">1</span>em<span class="token punctuation">;</span>
       vertical<span class="token operator">-</span>align<span class="token operator">:</span> <span class="token operator">-</span><span class="token number">0.15</span>em<span class="token punctuation">;</span>
       fill<span class="token operator">:</span> currentColor<span class="token punctuation">;</span>
       overflow<span class="token operator">:</span> hidden<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>style<span class="token operator">&gt;</span>
</code></pre></div><ul><li>第三步：挑选相应图标并获取类名，应用于页面</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>svg <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;icon&quot;</span> aria<span class="token operator">-</span>hidden<span class="token operator">=</span><span class="token string">&quot;true&quot;</span><span class="token operator">&gt;</span>
    <span class="token operator">&lt;</span>use xlink<span class="token operator">:</span>href<span class="token operator">=</span><span class="token string">&quot;#icon-xxx&quot;</span><span class="token operator">&gt;</span><span class="token operator">&lt;</span><span class="token operator">/</span>use<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>svg<span class="token operator">&gt;</span>
</code></pre></div><p><img src="/document/assets/img/1622601688139.af79f48c.png" alt="1622601688139"></p> <p><strong>总结：</strong> 把字体图标库的js文件引入在index.html，使用svg标签通过类名来指定图标。但是每次这样使用较为麻烦，结构比较多，还有样式，封装成组件。</p> <h3 id="_09-图标组件"><a href="#_09-图标组件" class="header-anchor">#</a> 09-图标组件</h3> <blockquote><p>目的：封装geek-icon组件来使用字体图标</p></blockquote> <p>大致步骤：</p> <ul><li>在components下定义geek-icon组件</li> <li>使用div.geek-icon包裹svg格式代码</li> <li>暴露props属性，name来指定图标</li></ul> <p>落地代码：</p> <ul><li>定义<code>src/components/geek-icon.vue</code></li></ul> <div class="language-VUE extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>geek-icon<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>svg</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>icon<span class="token punctuation">&quot;</span></span> <span class="token attr-name">aria-hidden</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>true<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>use</span> <span class="token attr-name">:xlink:href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>`#icon-${name}`<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>use</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>svg</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'GeekIcon'</span><span class="token punctuation">,</span>
  props<span class="token operator">:</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token punctuation">{</span>
      type<span class="token operator">:</span> String<span class="token punctuation">,</span>
      <span class="token keyword">default</span><span class="token operator">:</span> <span class="token string">''</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.geek-icon</span> <span class="token punctuation">{</span>
  <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span>
  <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token selector">;
  .icon</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 1em<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 1em<span class="token punctuation">;</span>
    <span class="token property">vertical-align</span><span class="token punctuation">:</span> -0.15em<span class="token punctuation">;</span>
    <span class="token property">fill</span><span class="token punctuation">:</span> currentColor<span class="token punctuation">;</span>
    <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>使用</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token deleted-arrow deleted"><span class="token prefix deleted">&lt;</span><span class="token line">template&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &lt;div class=&quot;home-page&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    首页 &lt;geek-icon style=&quot;font-size:50px;color:green&quot; name=&quot;weixin&quot;&gt;&lt;/geek-icon&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &lt;/div&gt;
</span></span><span class="token deleted-arrow deleted"><span class="token prefix deleted">&lt;</span><span class="token line">/template&gt;
</span><span class="token prefix deleted">&lt;</span><span class="token line">script&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import GeekIcon from '@/components/geek-icon'
</span></span>export default {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> name: 'HomePage',
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  components: { GeekIcon }
</span></span>}
<span class="token deleted-arrow deleted"><span class="token prefix deleted">&lt;</span><span class="token line">/script&gt;
</span><span class="token prefix deleted">&lt;</span><span class="token line">style scoped lang=&quot;less&quot;&gt;&lt;/style&gt;
</span></span></code></pre></div><p><strong>总结：</strong> 使用geek-icon组件name是图标名称，不需要加上icon。geek-icon的颜色和字体大小可控制图标颜色。</p> <p><strong>注意：</strong> weixin图标才可以测试改颜色，其他图标没有放开颜色的设置，需要去iconfont上进行设置。</p> <h3 id="_10-vue插件"><a href="#_10-vue插件" class="header-anchor">#</a> 10-Vue插件</h3> <blockquote><p>目标：掌握定义一个vue插件模块</p></blockquote> <p>大致步骤：</p> <ul><li>背景：项目开发过程中会有大量的一些自己写的全局组件，指令，过滤器，原型函数，如果都在main中书写，main的代码就很混乱，不利于维护。</li> <li>插件：可以扩展vue的原有功能在一个独立的js模块中。</li> <li>步骤：
<ul><li>定义一个js模块</li> <li>导出一个对象</li> <li>对象中有一个install属性指向的是一个函数</li> <li>函数的默认参数是 Vue</li> <li>你可以基于Vue做扩展功能</li></ul></li></ul> <p>落地代码：</p> <ul><li>定义插件 <code>src/components/index.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> GeekIcon <span class="token keyword">from</span> <span class="token string">'@/components/geek-icon'</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  <span class="token function">install</span> <span class="token punctuation">(</span><span class="token parameter">Vue</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 在这里扩展Vue功能</span>
    Vue<span class="token punctuation">.</span><span class="token function">component</span><span class="token punctuation">(</span>GeekIcon<span class="token punctuation">.</span>name<span class="token punctuation">,</span> GeekIcon<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>使用插件 <code>src/main.js</code></li></ul> <div class="language-j's extra-class"><pre class="language-text"><code>// 导入插件
import Geek from '@/components'
// 使用插件
Vue.use(Geek)
</code></pre></div><p><strong>总结：</strong> 我们在项目中一般会把 全局组件，过滤器，指令，定义在一个插件模块中。js模块的格式就是一个对象中有install函数即可。</p> <h3 id="_11-改造底部tab"><a href="#_11-改造底部tab" class="header-anchor">#</a> 11-改造底部Tab</h3> <blockquote><p>目标：自定义使用底部tab的图标</p></blockquote> <p>大致步骤：</p> <ul><li>需要使用icon插槽自定义图标</li> <li>需要使用icon插槽的props作用域数据切换图标状态</li> <li>需要使用/deep/来覆盖组件内部样式</li></ul> <p>落地代码：<code>src/components/app-tabbar.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar</span> <span class="token attr-name">:border</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>false<span class="token punctuation">&quot;</span></span> <span class="token attr-name">route</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>首页<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props.active ? <span class="token punctuation">'</span>home-sel<span class="token punctuation">'</span> : <span class="token punctuation">'</span>home<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/question<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>问答<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props.active ? <span class="token punctuation">'</span>qa-sel<span class="token punctuation">'</span> : <span class="token punctuation">'</span>qa<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/video<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>视频<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props.active ? <span class="token punctuation">'</span>video-sel<span class="token punctuation">'</span> : <span class="token punctuation">'</span>video<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabbar-item</span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/user<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>我的<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>props.active ? <span class="token punctuation">'</span>mine-sel<span class="token punctuation">'</span> : <span class="token punctuation">'</span>mine<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar-item</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabbar</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'GeekTabbar'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.van-tabbar</span> <span class="token punctuation">{</span>
  <span class="token property">background</span><span class="token punctuation">:</span> #F7F8FA<span class="token punctuation">;</span>
  <span class="token property">position</span><span class="token punctuation">:</span> static<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">/deep/ .van-tabbar-item--active</span> <span class="token punctuation">{</span>
  <span class="token property">color</span><span class="token punctuation">:</span> #FC6627<span class="token punctuation">;</span>
  <span class="token property">background-color</span><span class="token punctuation">:</span> #F7F8FA
<span class="token punctuation">}</span>
<span class="token selector">/deep/ .van-tabbar-item__icon</span> <span class="token punctuation">{</span>
  <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">/deep/ .van-tabbar-item__text</span> <span class="token punctuation">{</span>
  <span class="token property">font-size</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong> 使用van-tabbar-item的作用域插槽icon可以完成图标自定义和状态切换。</p> <p>样式中用到了几个颜色，这几个颜色是将来其他组件也会大量使用的，建议定义为全局变量。</p> <h3 id="_12-less全局变量"><a href="#_12-less全局变量" class="header-anchor">#</a> 12-Less全局变量</h3> <blockquote><p>目标：定项目的Less全局变量</p></blockquote> <p>大致步骤：</p> <ul><li>注意，如果你将less变量定义在一个less文件中，在使用变量的地方就需要引入这个文件，麻烦。</li> <li>所以，vue-cli考虑到这一点，提供了配置。 <a href="https://cli.vuejs.org/zh/guide/css.html#%E5%90%91%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8-loader-%E4%BC%A0%E9%80%92%E9%80%89%E9%A1%B9" target="_blank" rel="noopener noreferrer">参考配置<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <p>落地代码：</p> <ul><li>添加配置 <code>vue.config.js</code>  修改配置文件需要重启项目</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  css<span class="token operator">:</span> <span class="token punctuation">{</span>
    loaderOptions<span class="token operator">:</span> <span class="token punctuation">{</span>
      less<span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token comment">// 这里定义不需要加@，使用的时候需要加@  </span>
        globalVars<span class="token operator">:</span> <span class="token punctuation">{</span>
          <span class="token string">'geek-color'</span><span class="token operator">:</span> <span class="token string">'#FC6627'</span><span class="token punctuation">,</span>
          <span class="token string">'geek-gray-color'</span><span class="token operator">:</span> <span class="token string">'#F7F8FA'</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>使用变量 <code>src/components/app-tabbar.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>.van-tabbar {
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  background: @geek-gray-color;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> position: static;
</span></span>}
/deep/ .van-tabbar-item--active {
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  color: @geek-color;
</span><span class="token prefix inserted">+</span><span class="token line">  background-color: @geek-gray-color
</span></span>}
</code></pre></div><p><strong>总结：</strong> 在vue.config.js中添加配置就可以定义全局需要使用的less变量。</p> <h3 id="_13-vuex管理状态"><a href="#_13-vuex管理状态" class="header-anchor">#</a> 13-Vuex管理状态</h3> <blockquote><p>目标：使用vuex来管理项目中需要共享的数据模块</p></blockquote> <p>大致步骤：</p> <ul><li>定义 <code>user</code> 用户模块，维护用户 token 等信息，且需要同步本地存储。</li> <li>在 store 中使用 <code>user</code> 模块</li></ul> <p>落地代码：</p> <ul><li>user模块 <code>src/store/modules/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 用户模块</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  namespaced<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  <span class="token function">state</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      token<span class="token operator">:</span> localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">'geek-store-token'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  getters<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
  mutations<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function">setToken</span> <span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> token</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      state<span class="token punctuation">.</span>token <span class="token operator">=</span> token
      localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">'geek-store-token'</span><span class="token punctuation">,</span> token<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  actions<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div><ul><li>使用模块 <code>src/store/index.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> Vuex <span class="token keyword">from</span> <span class="token string">'vuex'</span>
<span class="token keyword">import</span> user <span class="token keyword">from</span> <span class="token string">'./modules/user'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Vuex<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">new</span> <span class="token class-name">Vuex<span class="token punctuation">.</span>Store</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  modules<span class="token operator">:</span> <span class="token punctuation">{</span>
    user
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

</code></pre></div><p><strong>总结：</strong>  今后组件间共享的数据由vuex来管理。</p> <h3 id="_14-请求工具-基础"><a href="#_14-请求工具-基础" class="header-anchor">#</a> 14-请求工具-基础</h3> <blockquote><p>目的：为了能单独维护axios的配置，提取一个请求工具模块。</p></blockquote> <p>大致步骤：</p> <ul><li>安装 <code>axios</code> 且导入到文件 <code>src/utils/request.js</code></li> <li>创建一个新的axios实例，配置 <code>baseURL</code> <code>timeout</code></li> <li>导出一个通过新axios实例调用接口的函数，返回值promise</li></ul> <p>落地代码： <code>src/utils/request.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> axios <span class="token keyword">from</span> <span class="token string">'axios'</span>

<span class="token comment">// 新axios实例</span>
<span class="token keyword">const</span> instance <span class="token operator">=</span> axios<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  baseURL<span class="token operator">:</span> <span class="token string">'http://geek.itheima.net/'</span><span class="token punctuation">,</span>
  timeout<span class="token operator">:</span> <span class="token number">5000</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// 导出一个新axios实例调用接口的函数，返回值promise</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token punctuation">,</span> method <span class="token operator">=</span> <span class="token string">'get'</span><span class="token punctuation">,</span> params<span class="token punctuation">,</span> data<span class="token punctuation">,</span> headers <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> promise <span class="token operator">=</span> <span class="token function">instance</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token punctuation">,</span> method<span class="token punctuation">,</span> params<span class="token punctuation">,</span> data<span class="token punctuation">,</span> headers <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> promise
<span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong> 将来通过导出的函数调接口即可。配置可以统一在这个文件进行维护。</p> <h3 id="_15-请求工具-赋能"><a href="#_15-请求工具-赋能" class="header-anchor">#</a> 15-请求工具-赋能</h3> <blockquote><p>目的：让请求工具能够处理，携带token问题，token失效问题。</p></blockquote> <p>大致步骤：</p> <ul><li>请求头携带token保持登录状态</li> <li>处理token失效问题，跳转登录页面，需要把在哪个页面失效的页面地址传递给登录页面，登录后回跳。</li></ul> <p>落地步骤：</p> <ul><li>请求头携带token保持登录状态</li></ul> <p>导入 <code>vuex</code> 仓库，然后在 请求拦截器  获取token信息，有就修改 <code>config</code> 的配置信息即可。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">'@/store'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 请求拦截器</span>
instance<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>request<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token parameter">config</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> token <span class="token operator">=</span> store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token
  <span class="token keyword">if</span> <span class="token punctuation">(</span>token<span class="token punctuation">)</span> config<span class="token punctuation">.</span>headers<span class="token punctuation">.</span>Authorization <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Bearer </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>token<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
  <span class="token keyword">return</span> config
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token parameter">err</span> <span class="token operator">=&gt;</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div><ul><li>处理token失效问题，跳转登录页面，需要把在哪个页面失效的页面地址传递给登录页面，登录后回跳。</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> router <span class="token keyword">from</span> <span class="token string">'@/router'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 响应拦截器</span>
instance<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token parameter">res</span> <span class="token operator">=&gt;</span> res<span class="token punctuation">,</span> <span class="token parameter">err</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">.</span>response <span class="token operator">&amp;&amp;</span> err<span class="token punctuation">.</span>response<span class="token punctuation">.</span>status <span class="token operator">===</span> <span class="token number">401</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// token失效</span>
    store<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">'user/setToken'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'/login?returnUrl='</span> <span class="token operator">+</span> <span class="token function">encodeURIComponent</span><span class="token punctuation">(</span>router<span class="token punctuation">.</span>currentRoute<span class="token punctuation">.</span>fullPath<span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>总结： 我们可以在<code>request.js</code> 配置扩展 axios 功能，处理项目需要的业务。</p> <h3 id="_16-await异常处理"><a href="#_16-await异常处理" class="header-anchor">#</a> 16-await异常处理</h3> <blockquote><p>目的：解决 <code>async await</code> 发请求，处理异常时候多出 <code>try catch</code> 代码块问题。</p></blockquote> <p>大致步骤：</p> <ul><li>使用封装好的请求函数调用接口处理成功和异常，总结 <code>try catch</code>  处理异常的缺点：需要额外的代码。</li> <li>使用 <code>await-to-js</code> 处理promise请求，处理成功和异常情况。</li> <li>优化 <code>request.js</code> 的请求函数，让返回的promise支持 <code>await-to-js</code> 写法。</li></ul> <p>落地代码：</p> <ul><li><ol><li>演示 <code>request.js</code> 调用接口处理成功和异常</li></ol></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'HomePage'</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">try</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> res <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/channels2'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'成功'</span><span class="token punctuation">,</span> res<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
    <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'失败'</span><span class="token punctuation">,</span> e<span class="token punctuation">.</span>message<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>我们发现：async await 调用接口，处理异常需要额外加 try catch 的代码块，代码层次增多，不好阅读。</p> <ul><li><ol start="2"><li>使用 <code>await-to-js</code> 配合 <code>request.js</code> 调用接口处理成功和异常</li></ol></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>
<span class="token keyword">import</span> to <span class="token keyword">from</span> <span class="token string">'await-to-js'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'HomePage'</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">to</span><span class="token punctuation">(</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/channels'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'失败'</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span>
    <span class="token keyword">else</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'成功'</span><span class="token punctuation">,</span> res<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>我们可以将 to 在request.js 工具中就使用，以后就不用每次引入 await-to-js，调用to函数。</p> <ul><li><ol start="3"><li>优化 <code>request.js</code> 代码</li></ol> <ul><li>安装 <code>npm i await-to-js</code></li> <li>导入 <code>import to from 'await-to-js'</code></li> <li>使用</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>export default ({ url, method = 'get', params, data, headers }) =&gt; {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> const promise = instance({ url, method, params, data, headers })
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  return to(promise)
</span></span>}
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'HomePage'</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/channels'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'失败'</span><span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span>
    <span class="token keyword">else</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'成功'</span><span class="token punctuation">,</span> res<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ul> <p><strong>总结：</strong> 使用await-to-js之后，可以通过是否存在 err 判断是否出现异常。不用使用try catch 增加代码。</p> <h3 id="_17-接口api函数"><a href="#_17-接口api函数" class="header-anchor">#</a> 17-接口API函数</h3> <blockquote><p>目的：知道提取API函数的目的，掌握这种套路。</p></blockquote> <p>发现问题：</p> <ul><li>问题：调用一个接口，需要传入：请求地址，请求方式，请求参数，等等。如果这个接口需要在多个组件调用，那么相同的代码需要写多次。</li> <li>解决：将接口的调用再次封装成为一个函数，只暴露请求参数。这样可以提高代码复用。</li></ul> <p>大致步骤：</p> <ul><li>根据接口文档封装一个接口函数</li> <li>再需要数据的组件导入调用函数</li></ul> <p>落的代码：（在首页获取频道信息）</p> <ul><li>定义API函数 <code>src/api/channel.js</code></li></ul> <div class="language-JS extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>

<span class="token comment">/**
 * 获取所有频道
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getAllChannels</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/channels'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>调用API函数 <code>src/views/home/index.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getAllChannels <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/channel'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'HomePage'</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 不使用err不写err即可，但是,号需要写</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getAllChannels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong> 以后调用接口，先写API函数，然后再调用API函数获取数据。</p> <h2 id="第三章-登录模块"><a href="#第三章-登录模块" class="header-anchor">#</a> 第三章：登录模块</h2> <h3 id="_01-登录-导航守卫"><a href="#_01-登录-导航守卫" class="header-anchor">#</a> 01-登录-导航守卫</h3> <blockquote><p>目的：访问用户相关页面都需要进行登录，做一个导航守卫进行登录拦截。</p></blockquote> <p>大致步骤：</p> <ul><li>约定好将来用户相关的页面 路由地址以 <code>/user</code> 开头</li> <li>在 <code>src/router/index.js</code>  添加前置导航守卫</li> <li>通过vuex中是否有 <code>token</code> 数据来判断是否登录，进行登录拦截。</li></ul> <p>落的代码： <code>src/router/index.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> store <span class="token keyword">from</span> <span class="token string">'@/store'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 导航守卫</span>
router<span class="token punctuation">.</span><span class="token function">beforeEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">to<span class="token punctuation">,</span> <span class="token keyword">from</span><span class="token punctuation">,</span> next</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> token <span class="token operator">=</span> store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token
  <span class="token comment">// 没登录却访问user下的路由</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>token <span class="token operator">&amp;&amp;</span> to<span class="token punctuation">.</span>path<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">'/user'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">next</span><span class="token punctuation">(</span><span class="token string">'/login?returnUrl='</span> <span class="token operator">+</span> <span class="token function">encodeURIComponent</span><span class="token punctuation">(</span>to<span class="token punctuation">.</span>fullPath<span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 其他情况放行</span>
  <span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>总结：</strong> 使用前置导航守卫拦截未登录却访问用户页面的情况。</p> <h3 id="_02-登录-组件布局"><a href="#_02-登录-组件布局" class="header-anchor">#</a> 02-登录-组件布局</h3> <blockquote><p>目的：完成登录页面基础布局，路由规则配置。</p></blockquote> <p>大致步骤：</p> <ul><li>定义登录组件</li> <li>配置路由规则</li> <li>完成基础布局</li></ul> <p>落的代码：</p> <ul><li>登录组件 <code>src/views/login/index.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>login-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>back<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- .native绑定组件的原生事件，属于组件根元素 --&gt;</span>
      <span class="token comment">&lt;!-- $router.back() 返回上一次访问路由，forward go --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">@click.native</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$router.back()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>esay-close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>短信登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 表单 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-form</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入手机号<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入验证码<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-form</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-button</span><span class="token punctuation">&gt;</span></span>登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-button</span><span class="token punctuation">&gt;</span></span>  
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'LoginPage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.login-page</span> <span class="token punctuation">{</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 0 32px<span class="token selector">;
  .back</span> <span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 60px<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token selector">;
    .geek-icon</span> <span class="token punctuation">{</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
      <span class="token property">color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span>
      <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
      <span class="token property">left</span><span class="token punctuation">:</span> -15px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.title</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 22px<span class="token punctuation">;</span>
    <span class="token property">line-height</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 30px 0<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-cell</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 20px 0<span class="token selector">;
    &amp;::after</span><span class="token punctuation">{</span>
      <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
      <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-button</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token property">margin-top</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
    <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span>to right<span class="token punctuation">,</span>#FF9999<span class="token punctuation">,</span>#FFA179<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>路由规则 <code>src/router/index.js</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">const Login = () =&gt; import('@/views/login')
</span></span>const routes = [
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">  // ...
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  { path: '/login', component: Login }
</span></span>]
</code></pre></div><p><strong>总结：</strong> 注意van-form和van-field是表单结构中的form和input他们需要结合使用。</p> <h3 id="_03-登录-表单校验"><a href="#_03-登录-表单校验" class="header-anchor">#</a> 03-登录-表单校验</h3> <blockquote><p>目标：完成表单项校验和提交时整体校验。</p></blockquote> <p>大致步骤：</p> <ul><li>通过文档了解vant校验的套路</li> <li>完成单个表单项的校验</li> <li>完成提交时整体校验</li></ul> <p>落地代码：</p> <ul><li>根据约定vant文档总结如下：</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>1. 通过van-field组件的rules属性指定校验规则，校验单个表单项
2. 校验规则具体参考：https://vant-contrib.gitee.io/vant/#/zh-CN/form#rule-shu-ju-jie-gou
3. 通过van-form组件提供的validate函数校验全部表单项
</code></pre></div><ul><li>完成单个表单项校验</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      form<span class="token operator">:</span> <span class="token punctuation">{</span>
        mobile<span class="token operator">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
        code<span class="token operator">:</span> <span class="token string">''</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      rules<span class="token operator">:</span> <span class="token punctuation">{</span>
        mobile<span class="token operator">:</span> <span class="token punctuation">[</span>
          <span class="token punctuation">{</span> required<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> message<span class="token operator">:</span> <span class="token string">'请输入手机号'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
          <span class="token punctuation">{</span> pattern<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^1[3-9]\d{9}$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> message<span class="token operator">:</span> <span class="token string">'手机号格式不对'</span> <span class="token punctuation">}</span>
        <span class="token punctuation">]</span><span class="token punctuation">,</span>
        code<span class="token operator">:</span> <span class="token punctuation">[</span>
          <span class="token punctuation">{</span> required<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> message<span class="token operator">:</span> <span class="token string">'请输入手机号'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
          <span class="token punctuation">{</span> pattern<span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^\d{6}$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> message<span class="token operator">:</span> <span class="token string">'验证码是6个数字'</span> <span class="token punctuation">}</span>
        <span class="token punctuation">]</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><div class="language-HTML extra-class"><pre class="language-html"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入手机号<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>form.mobile<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:rules</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>rules.mobile<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入验证码<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>form.code<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:rules</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>rules.code<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>完成提交时整体校验</li></ul> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-form</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>form<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>form<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function">login</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>form<span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'校验成功'</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong> 掌握单个表单项验证和整体验证可以完成大部分业务。</p> <h3 id="_04-登录-默认登录"><a href="#_04-登录-默认登录" class="header-anchor">#</a> 04-登录-默认登录</h3> <blockquote><p>目的：能够通过默认246810短信验证码完成登录</p></blockquote> <p>大致步骤：</p> <ul><li>由于短信业务需要接入第三方运营商需要买短信包，所以提供了246810默认的短信验证码。</li> <li>编写登录 API 接口函数</li> <li>使用 手机号 和 默认的短信验证码246810 进行登录</li> <li>成功后存储 token 信息</li></ul> <p>落地代码：</p> <ul><li>编写登录 API 接口函数 <code>src/api/index.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>

<span class="token comment">/**
 * 登录
 * @param {String} mobile - 手机号
 * @param {String} code - 验证码
 * @returns Promise
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">userLogin</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> mobile<span class="token punctuation">,</span> code <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'v1_0/authorizations'</span><span class="token punctuation">,</span>
    method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span>
    data<span class="token operator">:</span> <span class="token punctuation">{</span> mobile<span class="token punctuation">,</span> code <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

</code></pre></div><ul><li>使用 手机号 和 默认的短信验证码 进行登录  <code>src/views/login/index.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> userLogin <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token function">login</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 校验</span>
      <span class="token keyword">await</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>form<span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token comment">// 登录</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">userLogin</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>form<span class="token punctuation">)</span>
      <span class="token comment">// 失败</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'登录失败'</span><span class="token punctuation">)</span>
      <span class="token comment">// 成功</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><ul><li>成功后存储 token</li></ul> <p><code>src/views/login/index.vue</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> methods: {
</span><span class="token prefix unchanged"> </span><span class="token line">   async login () {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 校验
</span><span class="token prefix unchanged"> </span><span class="token line">     await this.$refs.form.validate()
</span><span class="token prefix unchanged"> </span><span class="token line">     // 登录
</span><span class="token prefix unchanged"> </span><span class="token line">     const [err, res] = await userLogin(this.form)
</span><span class="token prefix unchanged"> </span><span class="token line">     // 失败
</span><span class="token prefix unchanged"> </span><span class="token line">     if (err) return this.$toast.fail('登录失败')
</span><span class="token prefix unchanged"> </span><span class="token line">     // 成功
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      this.$store.commit('user/setToken', res.data.data.token)
</span><span class="token prefix inserted">+</span><span class="token line">      this.$router.push(this.$route.query.returnUrl || '/')
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span></code></pre></div><p><strong>总结：</strong> 定义API----&gt;调用API-----&gt;得到数据，会是以后的常态。我们存储token是后续会使用的。</p> <h3 id="_05-登录-短信登录"><a href="#_05-登录-短信登录" class="header-anchor">#</a> 05-登录-短信登录</h3> <blockquote><p>目的：完成发送短信验证码登录功能。</p></blockquote> <p>大致步骤：</p> <ul><li>准备 发送验证码 按钮</li> <li>编写发送短信API接口</li> <li>点击 发送验证码 按钮，
<ul><li>判断是否已经发送，</li> <li>校验手机号，</li> <li>调用发送短信API，</li> <li>成功后开启60秒倒计时，不可再次发送</li></ul></li></ul> <p>落地代码：</p> <ol><li>准备 发送验证码 按钮 <code>src/views/login/index.vue</code></li></ol> <div class="language-html extra-class"><pre class="language-html"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span> <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入验证码<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>form.code<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:rules</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>rules.code<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#button</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>send<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>发送验证码<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-css extra-class"><pre class="language-css"><code>  <span class="token selector">.send</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #A5A6AB<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
</code></pre></div><ol><li>编写发送短信API接口  <code>src/api/index.js</code></li></ol> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 发送短信验证码
 * @param {String} mobile - 手机号
 * @returns Promise
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">sendMessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">mobile</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/v1_0/sms/codes/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>mobile<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ol start="3"><li>点击 发送验证码 按钮，校验手机号，调用发送短信API，成功后开启60秒倒计时，不可再次发送</li></ol> <p><code>src/views/login/index.vue</code></p> <div class="language-js extra-class"><pre class="language-js"><code>      <span class="token comment">// 倒计时秒数</span>
      second<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
      <span class="token comment">// 定时器ID</span>
      timer<span class="token operator">:</span> <span class="token keyword">null</span>
</code></pre></div><div class="language-html extra-class"><pre class="language-html"><code>        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#button</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>send()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>send<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            {{second===0?'发送验证码':`${second}秒后发送`}}
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
     <span class="token comment">// 省略.... </span>
	<span class="token keyword">async</span> <span class="token function">send</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 已发送，不做事</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>second <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span>
      <span class="token comment">// 校验</span>
      <span class="token keyword">await</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>form<span class="token punctuation">.</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token string">'mobile'</span><span class="token punctuation">)</span>
      <span class="token comment">// 发短信</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">sendMessage</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>form<span class="token punctuation">.</span>mobile<span class="token punctuation">)</span>
      <span class="token comment">// 失败</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'发送失败'</span><span class="token punctuation">)</span>
      <span class="token comment">// 成功 倒计时</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>second <span class="token operator">=</span> <span class="token number">60</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>timer<span class="token punctuation">)</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>timer<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>timer <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>second<span class="token operator">--</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>second <span class="token operator">&lt;=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>timer<span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">beforeDestroy</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>timer<span class="token punctuation">)</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>timer<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">&lt;van-field v-model=&quot;form.mobile&quot; name=&quot;mobile&quot;
</span></span></code></pre></div><p><strong>总结：</strong> 对应定时器，最好在销毁组件前清除定时器。</p> <h2 id="第四章-首页模块"><a href="#第四章-首页模块" class="header-anchor">#</a> 第四章：首页模块</h2> <h3 id="_01-首页-频道展示"><a href="#_01-首页-频道展示" class="header-anchor">#</a> 01-首页-频道展示</h3> <blockquote><p>目的：完成首页频道TAB展示</p></blockquote> <p>大致步骤：</p> <ul><li>使用van-tabs组件完成基础结构</li> <li>放置搜索按钮和频道按钮再tab组件右侧</li> <li>获取频道数据，渲染van-tabs组件</li></ul> <p>落地代码：</p> <ul><li>使用van-tabs组件完成基础结构 <code>src/views/home/index.vue</code></li></ul> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabs</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tab</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>index in 8<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token punctuation">'</span>标签 <span class="token punctuation">'</span> + index<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    内容 {{ index }}
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tab</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabs</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">::v-deep .van-tabs</span> <span class="token punctuation">{</span>
   <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token selector">;  
  .van-tabs__line</span> <span class="token punctuation">{</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token atrule"><span class="token rule">@geek-color</span><span class="token punctuation">;</span></span>
    <span class="token property">height</span><span class="token punctuation">:</span> 2px<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 32px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-tab</span> <span class="token punctuation">{</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #9EA1AE<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-tab--active</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-tabs__wrap</span> <span class="token punctuation">{</span>
    <span class="token property">padding-right</span><span class="token punctuation">:</span> 86px<span class="token punctuation">;</span>
    <span class="token property">box-shadow</span><span class="token punctuation">:</span> 0 0 10px <span class="token function">rgba</span><span class="token punctuation">(</span>0<span class="token punctuation">,</span>0<span class="token punctuation">,</span>0<span class="token punctuation">,</span>0.1<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-tabs__content</span> <span class="token punctuation">{</span>
    <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
    <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-tab__pane</span> <span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>放置搜索按钮和频道按钮再van-tabs组件下面，定位到右上角  <code>src/views/home/index.vue</code></li></ul> <div class="language-html extra-class"><pre class="language-html"><code>    <span class="token comment">&lt;!-- 按钮 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn-wrapper<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>search<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>channel<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">.home-page</span> <span class="token punctuation">{</span>
  <span class="token selector">.btn-wrapper</span> <span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
    <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 86px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 44px<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token selector">;
    .geek-icon</span> <span class="token punctuation">{</span>
      <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
      <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token selector">&amp;::before</span> <span class="token punctuation">{</span>
      <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">;</span>
      <span class="token property">width</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 44px<span class="token punctuation">;</span>
      <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
      <span class="token property">left</span><span class="token punctuation">:</span> -20px<span class="token punctuation">;</span>
      <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
      <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span>to right<span class="token punctuation">,</span> <span class="token function">rgba</span><span class="token punctuation">(</span>255<span class="token punctuation">,</span>255<span class="token punctuation">,</span>255<span class="token punctuation">,</span>0<span class="token punctuation">)</span><span class="token punctuation">,</span> #fff<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>获取频道数据，渲染van-tabs组件</li></ul> <p><code>src/api/channel.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取我的频道（未登录会返回默认的一些频道）
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getMyChannels</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/user/channels'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p><code>src/views/home/index.vue</code></p> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      myChannels<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 不使用err不写err即可，但是,号需要写</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getMyChannels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>channels
  <span class="token punctuation">}</span>
</code></pre></div><div class="language-html extra-class"><pre class="language-html"><code>    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabs</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tab</span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.id<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item in myChannels<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        内容 {{ item.id }}
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tab</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-tabs</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong> 完成tab使用，改造样式布局，获取频道数据，渲染即可。</p> <h3 id="_02-首页-文章组件"><a href="#_02-首页-文章组件" class="header-anchor">#</a> 02-首页-文章组件</h3> <blockquote><p>目的：完成文章列表组件与文章单项组件</p></blockquote> <p>大概步骤：</p> <ul><li>准备文章单项组件</li> <li>准备文章列表组件</li> <li>首页使用文章列表组件</li> <li>首页van-tabs样式修改</li></ul> <p>落的步骤：</p> <ul><li>准备文章单项组件 <code>src/views/home/components/article-item.vue</code></li></ul> <p>1）无图</p> <div class="language-html extra-class"><pre class="language-html"><code>  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-item van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title van-multi-ellipsis--l2<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>美国强行关闭33家伊朗网站 伊总统办公室警告：不利于伊核谈判<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>小兵张嘎<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>17评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>1天前<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>esay-close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>2）三图</p> <div class="language-html extra-class"><pre class="language-html"><code>  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-item van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title van-multi-ellipsis--l2<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>美国强行关闭33家伊朗网站 伊总统办公室警告：不利于伊核谈判<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>img<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://inews.gtimg.com/newsapp_ls/0/13685285688_294195/0<span class="token punctuation">&quot;</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>img<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://inews.gtimg.com/newsapp_ls/0/13685285688_294195/0<span class="token punctuation">&quot;</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>img<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://inews.gtimg.com/newsapp_ls/0/13685285688_294195/0<span class="token punctuation">&quot;</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>小兵张嘎<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>17评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>1天前<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>esay-close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>3）单图，title处加了w66的类名需要注意</p> <div class="language-html extra-class"><pre class="language-html"><code>  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-item van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title van-multi-ellipsis--l2 w66<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>美国强行关闭33家伊朗网站 伊总统办公室警告：不利于伊核谈判<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>img<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://inews.gtimg.com/newsapp_ls/0/13685285688_294195/0<span class="token punctuation">&quot;</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>小兵张嘎<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>17评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>1天前<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>esay-close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>其他代码</p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticleItem'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.article-item</span> <span class="token punctuation">{</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 15px 0<span class="token punctuation">;</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">flex-wrap</span><span class="token punctuation">:</span> wrap<span class="token punctuation">;</span>
  <span class="token property">justify-content</span><span class="token punctuation">:</span> space-between<span class="token selector">;
  .title</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">line-height</span><span class="token punctuation">:</span> 22px<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span>
    <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 8px<span class="token punctuation">;</span>
    <span class="token property">max-height</span><span class="token punctuation">:</span> 44px<span class="token selector">;
    &amp;.w66</span> <span class="token punctuation">{</span>
      <span class="token property">width</span><span class="token punctuation">:</span> 66%<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.img</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 112px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 74px<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> 4px<span class="token punctuation">;</span>
    <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 8px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.info</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #A5A6AB<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token selector">;
    span</span> <span class="token punctuation">{</span>
      <span class="token property">margin-right</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token selector">.geek-icon</span> <span class="token punctuation">{</span>
      <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>

</code></pre></div><ul><li>准备文章列表组件 <code>src/views/home/components/article-list.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-list<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-item</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i in 10<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> ArticleItem <span class="token keyword">from</span> <span class="token string">'./article-item.vue'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticleList'</span><span class="token punctuation">,</span>
  components<span class="token operator">:</span> <span class="token punctuation">{</span>
    ArticleItem
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.article-list</span> <span class="token punctuation">{</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">overflow-y</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 0 16px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>首页使用文章列表组件  <code>src/views/home/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>import { getMyChannels } from '@/api/channel'
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import ArticleList from './components/article-list.vue'
</span></span>export default {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> name: 'HomePage',
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  components: { ArticleList },
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;van-tabs&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-tab :key=&quot;item.id&quot; v-for=&quot;item in myChannels&quot; :title=&quot;item.name&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        &lt;article-list&gt;&lt;/article-list&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;/van-tab&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-tabs&gt;
</span></span></code></pre></div><ul><li>首页van-tabs样式修改  <code>src/views/home/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>::v-deep .van-tabs {
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  height: 100%;
</span><span class="token prefix inserted">+</span><span class="token line">  display: flex;
</span><span class="token prefix inserted">+</span><span class="token line">  flex-direction: column;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> .van-tabs__line {
</span><span class="token prefix unchanged"> </span><span class="token line">   background: @geek-color;
</span><span class="token prefix unchanged"> </span><span class="token line">   height: 2px;
</span><span class="token prefix unchanged"> </span><span class="token line">   width: 32px;
</span><span class="token prefix unchanged"> </span><span class="token line"> }
</span><span class="token prefix unchanged"> </span><span class="token line"> .van-tab {
</span><span class="token prefix unchanged"> </span><span class="token line">   color: #9EA1AE;
</span><span class="token prefix unchanged"> </span><span class="token line"> }
</span><span class="token prefix unchanged"> </span><span class="token line"> .van-tab--active {
</span><span class="token prefix unchanged"> </span><span class="token line">   font-size: 18px;
</span><span class="token prefix unchanged"> </span><span class="token line">   color: #333;
</span><span class="token prefix unchanged"> </span><span class="token line"> }
</span><span class="token prefix unchanged"> </span><span class="token line"> .van-tabs__wrap {
</span><span class="token prefix unchanged"> </span><span class="token line">   padding-right: 86px;
</span><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  .van-tabs__content {
</span><span class="token prefix inserted">+</span><span class="token line">    flex: 1;
</span><span class="token prefix inserted">+</span><span class="token line">    overflow: hidden;
</span><span class="token prefix inserted">+</span><span class="token line">  }
</span><span class="token prefix inserted">+</span><span class="token line">  .van-tab__pane {
</span><span class="token prefix inserted">+</span><span class="token line">    height: 100%;
</span><span class="token prefix inserted">+</span><span class="token line">  }
</span></span>}
</code></pre></div><p><strong>总结：</strong> 注意下单图无图三图结构情况，注意下flex布局占满剩余高度产生滚动条。</p> <h3 id="_03-首页-上拉加载"><a href="#_03-首页-上拉加载" class="header-anchor">#</a> 03-首页-上拉加载</h3> <blockquote><p>目的：实现上拉加载效果</p></blockquote> <p>大致步骤：</p> <ul><li>使用van-list组件，知道需要使用属性和事件作用</li> <li>模拟上拉加载效果</li></ul> <p>落地代码：<code>src/views/home/components/article-list.vue</code></p> <ul><li>使用van-list组件，知道需要使用属性和事件作用</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-list<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-list</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>loading<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:finished</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>finished<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@load</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>onLoad()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">finished-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>没有更多了<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-item</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i in 10<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-list</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> ArticleItem <span class="token keyword">from</span> <span class="token string">'./article-item.vue'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticleList'</span><span class="token punctuation">,</span>
  components<span class="token operator">:</span> <span class="token punctuation">{</span>
    ArticleItem
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      <span class="token comment">// 正在加载</span>
      loading<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
      <span class="token comment">// 数据全部加载完毕</span>
      finished<span class="token operator">:</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function">onLoad</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'上拉加载'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><code>v-model=&quot;loading&quot;</code> 是加载中状态，控制显示加载中效果，<code>:finished=&quot;finished&quot;</code> 是显示是否完全加载完毕数据，</p> <p><code>@load=&quot;onLoad()&quot;</code> 是上拉加载后事件，当列表最底部进入可视区（能看见列表末尾）就会触发上拉加载事件。</p> <ul><li>模拟上拉加载效果</li></ul> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-item</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>(item, i) in articles<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 正在加载
</span><span class="token prefix unchanged"> </span><span class="token line">     loading: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 数据全部加载完毕
</span><span class="token prefix unchanged"> </span><span class="token line">     finished: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 文章列表
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      articles: []
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function">onLoad</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 模拟请求</span>
      <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token comment">// 加载完毕</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>loading <span class="token operator">=</span> <span class="token boolean">false</span>
        <span class="token comment">// 判断还有没有数据</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>articles<span class="token punctuation">.</span>length <span class="token operator">&lt;</span> <span class="token number">40</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token comment">// 设置数据，追加</span>
          <span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span>
          <span class="token keyword">this</span><span class="token punctuation">.</span>articles<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token operator">...</span>data<span class="token punctuation">)</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
          <span class="token comment">// 设置数据全部加载完毕</span>
          <span class="token keyword">this</span><span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">true</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong> 知道van-list的属性和事件，知道加载数据的套路。</p> <h3 id="_04-首页-下拉刷新"><a href="#_04-首页-下拉刷新" class="header-anchor">#</a> 04-首页-下拉刷新</h3> <blockquote><p>目的：实现下拉刷新效果</p></blockquote> <p>大致步骤：<code>src/views/home/components/article-list.vue</code></p> <ul><li>使用 van-pull-refresh 组件，知道需要使用的属性和事件作用</li> <li>模拟下拉刷新效果</li></ul> <p>落地代码：</p> <ul><li>使用 van-pull-refresh 组件，知道需要使用的属性和事件作用</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;van-pull-refresh
</span><span class="token prefix inserted">+</span><span class="token line">      v-model=&quot;refreshing&quot;
</span><span class="token prefix inserted">+</span><span class="token line">      @refresh=&quot;onRefresh&quot;
</span><span class="token prefix inserted">+</span><span class="token line">      success-text=&quot;刷新成功&quot;
</span><span class="token prefix inserted">+</span><span class="token line">    &gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-list
</span><span class="token prefix unchanged"> </span><span class="token line">       v-model=&quot;loading&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       :finished=&quot;finished&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       @load=&quot;onLoad()&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       finished-text=&quot;没有更多了&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">     &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;article-item v-for=&quot;i in articles&quot; :key=&quot;i&quot; /&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/van-list&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;/van-pull-refresh&gt;
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 正在加载
</span><span class="token prefix unchanged"> </span><span class="token line">     loading: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 数据全部加载完毕
</span><span class="token prefix unchanged"> </span><span class="token line">     finished: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 文章列表
</span><span class="token prefix unchanged"> </span><span class="token line">     articles: [],
</span><span class="token prefix unchanged"> </span><span class="token line">     // 正在刷新
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      refreshing: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> methods: {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    onRefresh () {
</span><span class="token prefix inserted">+</span><span class="token line">      console.log('下拉刷新')
</span><span class="token prefix inserted">+</span><span class="token line">    },
</span></span></code></pre></div><p><code>v-model=&quot;refreshing&quot;</code> 是刷新中状态，控制显示刷新中效果，<code>loading-text&quot;</code> 是设置刷新中的提示文字，</p> <p><code>@refresh=&quot;onRefresh()&quot;</code> 是下拉刷新后事件，当用户向下拖动到一定距离后会触发下拉刷新事件。</p> <ul><li>模拟下拉刷新效果</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token function">onRefresh</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 模拟请求</span>
      <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token comment">// 刷新完毕</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>refreshing <span class="token operator">=</span> <span class="token boolean">false</span>
        <span class="token comment">// 设置数据全部加载完毕为：未加载完</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">false</span>
        <span class="token comment">// 设置数据，替换</span>
        <span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>articles <span class="token operator">=</span> data
      <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><p>需要注意下的是，刷新完毕后需要 将 <code>finished</code> 改成 <code>false</code> 代表还可以继续上拉加载数据，因为重置了列表数据。</p> <p><strong>总结：</strong> 知道 van-pull-refresh 组件 v-model 的作用是控制刷新中状态，@refresh 是监听下拉刷新事件。然后由于重置了数据，需要将列表改成还有更多数据状态。</p> <h3 id="_05-首页-接入数据"><a href="#_05-首页-接入数据" class="header-anchor">#</a> 05-首页-接入数据</h3> <blockquote><p>目的：调用接口获取文章列表真实的数据，完成数据渲染。</p></blockquote> <p>大致步骤：</p> <ul><li>每个频道对应自己的列表，需要传入频道ID给文章列表组件。</li> <li>编写获取文章列表的API接口函数</li> <li>再上拉加载和下拉加载的位置接入真实的接口</li> <li>渲染单项文章组件</li></ul> <p>落地代码：</p> <ul><li>每个频道对应自己的列表，需要传入频道ID给文章列表组件。</li></ul> <p><code>src/views/home/index.vue</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;van-tabs&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-tab :key=&quot;item.id&quot; v-for=&quot;item in myChannels&quot; :title=&quot;item.name&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        &lt;article-list :channelId=&quot;item.id&quot;&gt;&lt;/article-list&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;/van-tab&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-tabs&gt;
</span></span></code></pre></div><p><code>src/views/home/components/article-list.vue</code></p> <div class="language-js extra-class"><pre class="language-js"><code>  props<span class="token operator">:</span> <span class="token punctuation">{</span>
    channelId<span class="token operator">:</span> <span class="token punctuation">{</span>
      type<span class="token operator">:</span> Number<span class="token punctuation">,</span>
      <span class="token keyword">default</span><span class="token operator">:</span> <span class="token number">0</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>编写获取文章列表的API接口函数</li></ul> <p><code>src/api/article.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>

<span class="token comment">/**
 * 根据频道获取频道
 * @param {Number} channelId - 频道ID
 * @param {Number} timestamp - 时间戳
 * @returns
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getArticlesByChannel</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">channelId<span class="token punctuation">,</span> timestamp</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/articles'</span><span class="token punctuation">,</span>
    method<span class="token operator">:</span> <span class="token string">'get'</span><span class="token punctuation">,</span>
    params<span class="token operator">:</span> <span class="token punctuation">{</span>
      channel_id<span class="token operator">:</span> channelId<span class="token punctuation">,</span>
      timestamp
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>在上拉加载和下拉加载的位置接入真实的接口</li></ul> <p><code>src/views/home/components/article-list.vue</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getArticlesByChannel <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/article'</span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 正在加载
</span><span class="token prefix unchanged"> </span><span class="token line">     loading: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 数据全部加载完毕
</span><span class="token prefix unchanged"> </span><span class="token line">     finished: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 文章列表
</span><span class="token prefix unchanged"> </span><span class="token line">     articles: [],
</span><span class="token prefix unchanged"> </span><span class="token line">     // 正在刷新
</span><span class="token prefix unchanged"> </span><span class="token line">     refreshing: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 时间戳
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      timestamp: Date.now()
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token keyword">async</span> <span class="token function">onRefresh</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 下拉刷新</span>
      <span class="token comment">// 1. 重置时间戳：回到第一页</span>
      <span class="token comment">// 2. 获取数据</span>
      <span class="token comment">// 3. 重置全部数据加载完成：可以再次加载更多</span>
      <span class="token comment">// 4. 替换当前列表数据戳</span>
      <span class="token comment">// 5. 记录下一次请求的时间</span>
      <span class="token comment">// 6. 结束加刷新操作</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>timestamp <span class="token operator">=</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getArticlesByChannel</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>channelId<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>timestamp<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>articles <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>results
      <span class="token keyword">this</span><span class="token punctuation">.</span>timestamp <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>pre_timestamp
      <span class="token keyword">this</span><span class="token punctuation">.</span>refreshing <span class="token operator">=</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token keyword">async</span> <span class="token function">onLoad</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 上拉加载</span>
      <span class="token comment">// 1. 获取数据</span>
      <span class="token comment">// 2. 判断下一页是否还有数据：当前时间戳未空，也就是没有更多了</span>
      <span class="token comment">// 2.1 如果有：记录当前的数据时间戳，下一次请求使用</span>
      <span class="token comment">// 2.2 如没有：设置没有更多数据</span>
      <span class="token comment">// 3. 当前列表追加数据   </span>
      <span class="token comment">// 4. 结束上拉加载操作</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getArticlesByChannel</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>channelId<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>timestamp<span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'加载失败'</span><span class="token punctuation">)</span>  <span class="token comment">// 加载失败</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>pre_timestamp<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>timestamp <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>pre_timestamp
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token punctuation">}</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>articles<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token operator">...</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>results<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>loading <span class="token operator">=</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><ul><li>渲染单项文章组件</li></ul> <p><code>src/views/home/components/article-list.vue</code> 传入文章信息</p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-item</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>(item, i) in articles<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:article</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><p><code>src/views/home/components/article-item.vue</code> 使用文章信息</p> <div class="language-js extra-class"><pre class="language-js"><code>  props<span class="token operator">:</span> <span class="token punctuation">{</span>
    article<span class="token operator">:</span> <span class="token punctuation">{</span>
      type<span class="token operator">:</span> Object<span class="token punctuation">,</span>
      <span class="token function-variable function">default</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-item van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title van-multi-ellipsis--l2<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>{w66: article.cover.type===1}<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{article.title}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>(url,i) in article.cover.images<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>img<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>url<span class="token punctuation">&quot;</span></span> <span class="token attr-name">alt</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.aut_name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.comm_count}}评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.pubdate}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>esay-close<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong> 使用传入的频道ID获取数据，在上拉和下拉后等所有的逻辑完成后，结束加载或刷新状态。</p> <h3 id="_06-首页-处理时间"><a href="#_06-首页-处理时间" class="header-anchor">#</a> 06-首页-处理时间</h3> <blockquote><p>目的：把文章发布时间转换为相对时间，例如：2个月内，1分钟内。</p></blockquote> <p>大致步骤：</p> <ul><li>定义一个过滤器，使用过滤器证明可用。</li> <li>然后在过滤中实现转换逻辑，采用 dayjs 时间库处理。
<ul><li>安装导入 dayjs</li> <li>使用 relativeTime 模块转化相对时间</li> <li>使用 locale 默认语言本地化</li></ul></li></ul> <p>落地代码：</p> <ul><li>定义一个过滤器，使用过滤器证明可用。</li></ul> <p><code>src/components/index.js</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code>export default {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> install (Vue) {
</span><span class="token prefix unchanged"> </span><span class="token line">   // 在这里扩展Vue功能
</span><span class="token prefix unchanged"> </span><span class="token line">   Vue.component(GeekIcon.name, GeekIcon)
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    // 全局注册过滤器
</span><span class="token prefix inserted">+</span><span class="token line">    Vue.filter('relativeTime', (value) =&gt; {
</span><span class="token prefix inserted">+</span><span class="token line">      return '1周内'
</span><span class="token prefix inserted">+</span><span class="token line">    })
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span>}
</code></pre></div><p><code>src/views/home/components/article-item.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.pubdate|relativeTime}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>然后在过滤中实现转换逻辑，采用 dayjs 时间库处理。</li></ul> <p><code>src/components/index.js</code></p> <p>1）安装</p> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">npm</span> i dayjs
</code></pre></div><p>2）导入</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> dayjs <span class="token keyword">from</span> <span class="token string">'dayjs'</span>
</code></pre></div><p>3）使用 相对时间 插件</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> relativeTime <span class="token keyword">from</span> <span class="token string">'dayjs/plugin/relativeTime'</span>
dayjs<span class="token punctuation">.</span><span class="token function">extend</span><span class="token punctuation">(</span>relativeTime<span class="token punctuation">)</span>
</code></pre></div><p>4）进行时间转换</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   // 全局注册过滤器
</span><span class="token prefix unchanged"> </span><span class="token line">   Vue.filter('relativeTime', (value) =&gt; {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      return dayjs(value).toNow()
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   })
</span></span></code></pre></div><p>5）本地化，语言</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token string">'dayjs/locale/zh-cn'</span>
dayjs<span class="token punctuation">.</span><span class="token function">locale</span><span class="token punctuation">(</span><span class="token string">'zh-cn'</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>总结：</strong> 知道过滤器的注册使用，知道dayjs的基本使用。</p> <h3 id="_07-首页-组件缓存"><a href="#_07-首页-组件缓存" class="header-anchor">#</a> 07-首页-组件缓存</h3> <blockquote><p>目的：首页的状态（当前浏览的频道，频道里头文章）需要保持，当你切换到其他页面时。</p></blockquote> <p>大致步骤：</p> <ul><li>知道如何通过组件缓存来保存组件状态</li> <li>知道如何指定某些组件进行缓存</li> <li>知道如何判断组件确实缓存了</li></ul> <p>落地代码：</p> <p><code>src/App.vue</code></p> <ul><li>使用 keep-alive 来缓存组件</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &lt;div id=&quot;app&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;keep-alive&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;RouterView class=&quot;body&quot; /&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;/keep-alive&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;RouterView class=&quot;footer&quot; name=&quot;tabbar&quot; /&gt;
</span><span class="token prefix unchanged"> </span><span class="token line"> &lt;/div&gt;
</span></span></code></pre></div><p>那么将来 <code>RouterView</code> 动态展示的组件都会被缓存</p> <ul><li>使用 include 来指定需要被缓存的组件</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">&lt;</span>keep<span class="token operator">-</span>alive include<span class="token operator">=</span><span class="token string">&quot;HomePage&quot;</span><span class="token operator">&gt;</span>
</code></pre></div><p>属性的值是需要缓存组件的name名称，如果多个组件可以 逗号 分隔 <code>a,b,c</code></p> <ul><li>我们可以通过 devtools 观察组件是否缓存</li></ul> <p><img src="/document/assets/img/1624590995437.410d2b6f.png" alt="1624590995437"></p> <p>看见 inactive 代表当前组件被缓存，或者切换下组件看看组件数据状态是否保存住，还有组件被缓存了再次进入组件是不会触发 created 钩子的这也可以判断。</p> <p><strong>总结：</strong> 知道使用keep-alive组件缓存组件，知道使用include来制定被缓存组件。</p> <h3 id="_08-首页-阅读位置"><a href="#_08-首页-阅读位置" class="header-anchor">#</a> 08-首页-阅读位置</h3> <blockquote><p>目的：组件缓存只会缓存状态数据，而滚动的位置（阅读位置）没有保持，我们需要完成阅读位置保持。</p></blockquote> <p>大致步骤：</p> <ul><li>我们需要知道如何监听：进入组件（激活组件）</li> <li>我们需要在阅读列表的时候记录当前滚动位置</li> <li>我们需要在进入组件的时候还原之前滚动位置</li></ul> <p>落地代码：</p> <p><code>src/views/home/components/article-list.vue</code></p> <ul><li><code>activated</code> 和 <code>deactivated</code> 将会在 <code>keep-alive</code> 树内的所有嵌套组件中触发 <a href="https://cn.vuejs.org/v2/api/#keep-alive" target="_blank" rel="noopener noreferrer">参考文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li>我们需要在阅读列表的时候记录当前滚动位置</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>      <span class="token comment">// 阅读位置 (data中申明)</span>
      scrollTop<span class="token operator">:</span> <span class="token number">0</span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-list<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ArticleList<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@scroll</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>rememberScroll<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// 滚动监听</span>
    <span class="token function">rememberScroll</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>scrollTop <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>ArticleList<span class="token punctuation">.</span>scrollTop
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>我们需要在进入组件的时候还原之前滚动位置</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token comment">// 激活组件</span>
  <span class="token function">activated</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>ArticleList<span class="token punctuation">.</span>scrollTop <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>scrollTop
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><p><strong>注意：</strong> <code>src/views/home/index.vue</code></p> <p>如果当前列表被隐藏，滚动失效，需要设置 animated 有动画的时候，所有列表不会隐藏，激活的时候滚动生效。</p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-tabs</span> <span class="token attr-name">animated</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong>  监听 article-list 的 scroll 事件记录 scrollTop , 然后在组件触发 activated 事件设置 article-list 的 scrollTop 最后注意 van-tabs 加上 animated 属性。</p> <p>先定义API函数，组件中调用即可。</p> <ul><li>van-tabs 组件实现频道</li> <li>van-list 组件实现上拉加载</li> <li>van-pull-refresh 组件实现下拉刷新</li> <li>dayjs relativeTime模块  定义过滤器  处理时间</li> <li>keep-alive vue内置组件做了缓存</li> <li>记录位置，组件激活 activated 还原位置</li></ul> <p>回顾 promise 知识</p> <ul><li>异步操作有回调函数，如果有嵌套，形成逻辑不是特别清楚的代码，回调地狱</li> <li>promise 可以解决回调地狱问题，可以让异步操作使用then串联执行</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// promise</span>
<span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'url1'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'url2'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><ul><li>async await 可以让promise的代码更加简洁</li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> getData <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token operator">&gt;</span><span class="token punctuation">{</span>
 <span class="token keyword">await</span> <span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'url1'</span><span class="token punctuation">)</span>
 <span class="token keyword">await</span> <span class="token function">ajax</span><span class="token punctuation">(</span><span class="token string">'url2'</span><span class="token punctuation">)</span> 
<span class="token punctuation">}</span>
</code></pre></div><h2 id="第五章-频道管理"><a href="#第五章-频道管理" class="header-anchor">#</a> 第五章：频道管理</h2> <h3 id="_01-频道-组件准备"><a href="#_01-频道-组件准备" class="header-anchor">#</a> 01-频道-组件准备</h3> <blockquote><p>目的：定义频道管理组件，准备一个弹出层组件，在首页组件使用频道管理组件。</p></blockquote> <p>大致步骤：</p> <ul><li>了解 van-popup 组件基本用法</li> <li>定义频道管理组件，使用van-popup组件，修改样式</li> <li>在首页组件使用频道管理组件
<ul><li>实现:value来控制van-popup的显示</li> <li>实现@input来控制van-popup的隐藏</li> <li>简写成v-model</li></ul></li></ul> <p>落地代码：</p> <ul><li>了解 van-popup 组件基本用法 <a href="https://vant-contrib.gitee.io/vant/#/zh-CN/popup#api" target="_blank" rel="noopener noreferrer">参考文档<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>1. v-model 或者 value 控制 弹出层显示和隐藏，值类型 true false
2. position 弹出的位置 left top bottom right
3. closeable 是否显示关闭图标
4. 事件 click-close-icon 点击关闭按钮的事件
5. 弹层大小，图标大小，使用样式覆盖控制
</code></pre></div><ul><li>定义频道管理组件，使用van-popup组件，修改样式</li></ul> <p>定义组件  <code>src/views/home/components/article-channel.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-popup</span>
    <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>value<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">@click-close-icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$emit(<span class="token punctuation">'</span>input<span class="token punctuation">'</span>, false)<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">closeable</span>
    <span class="token attr-name">position</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>left<span class="token punctuation">&quot;</span></span>
  <span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-channel<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      频道管理
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-popup</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticleChannel'</span><span class="token punctuation">,</span>
  props<span class="token operator">:</span> <span class="token punctuation">{</span>
    value<span class="token operator">:</span> <span class="token punctuation">{</span>
      type<span class="token operator">:</span> Boolean<span class="token punctuation">,</span>
      <span class="token keyword">default</span><span class="token operator">:</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.van-popup</span> <span class="token punctuation">{</span>
  <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token selector">;
  ::v-deep .van-popup__close-icon</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
    <span class="token property">right</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token selector">.article-channel</span> <span class="token punctuation">{</span>
  <span class="token property">margin-top</span><span class="token punctuation">:</span> 44px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>使用组件 <code>src/views/home/index.vue</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">import ArticleChannel from './components/article-channel.vue'
</span></span>export default {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> name: 'HomePage',
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  components: { ArticleList, ArticleChannel },
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 按钮 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;div class=&quot;btn-wrapper&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;geek-icon name=&quot;search&quot;&gt;&lt;/geek-icon&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;geek-icon name=&quot;channel&quot; @click.native=&quot;showChannel=true&quot;&gt;&lt;/geek-icon&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;/div&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 频道 --&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;article-channel v-model=&quot;showChannel&quot;&gt;&lt;/article-channel&gt;
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     myChannels: [],
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      // 控制频道组件显示隐藏
</span><span class="token prefix inserted">+</span><span class="token line">      showChannel: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><p><strong>总结：</strong> 封装频道管理组件，实现v-model指令，控制van-popup显示隐藏。</p> <h3 id="_02-频道-组件布局"><a href="#_02-频道-组件布局" class="header-anchor">#</a> 02-频道-组件布局</h3> <blockquote><p>目的：完成频道组件的基础布局，了解需要动态交互的点。</p></blockquote> <p>大致步骤：</p> <ul><li>准备HTML结构</li> <li>准备CSS样式</li> <li>了解动态修改的类名</li></ul> <p>落地代码：<code>src/views/home/components/article-channel.vue</code></p> <ul><li>准备HTML结构</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token deleted-arrow deleted"><span class="token prefix deleted">&lt;</span><span class="token line">template&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &lt;van-popup
</span><span class="token prefix unchanged"> </span><span class="token line">   :value=&quot;value&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">   @click-close-icon=&quot;$emit('input', false)&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">   closeable
</span><span class="token prefix unchanged"> </span><span class="token line">   position=&quot;left&quot;
</span><span class="token prefix unchanged"> </span><span class="token line"> &gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;div class=&quot;article-channel&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;div class=&quot;head&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;h3&gt;我的频道&lt;small&gt;点击进入频道&lt;/small&gt;&lt;/h3&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;a class=&quot;edit&quot; href=&quot;javascript:;&quot;&gt;编辑&lt;/a&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;/div&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;div class=&quot;body&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;a href=&quot;javascript:;&quot; class=&quot;active&quot;&gt;推荐&lt;/a&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;a href=&quot;javascript:;&quot; v-for=&quot;i in 8&quot; :key=&quot;i&quot;&gt;频道{{i}}&lt;/a&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;/div&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;div class=&quot;head&quot; style=&quot;margin-top:12px&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;h3&gt;频道推荐&lt;/h3&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;/div&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;div class=&quot;body&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;a href=&quot;javascript:;&quot; v-for=&quot;i in 15&quot; :key=&quot;i&quot;&gt;+ 频道{{i}}&lt;/a&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;/div&gt;
</span><span class="token prefix inserted">+</span><span class="token line">    &lt;/div&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &lt;/van-popup&gt;
</span></span><span class="token deleted-arrow deleted"><span class="token prefix deleted">&lt;</span><span class="token line">/template&gt;
</span></span></code></pre></div><ul><li>准备CSS样式</li></ul> <div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">.article-channel</span> <span class="token punctuation">{</span>
  <span class="token property">margin-top</span><span class="token punctuation">:</span> 44px<span class="token punctuation">;</span>
  <span class="token selector">.head</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 16px<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> space<span class="token operator">-</span>between<span class="token punctuation">;</span>
    <span class="token property">justify-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">padding-bottom</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token selector">h3</span> <span class="token punctuation">{</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
      <span class="token property">color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span>
      <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
      <span class="token selector">small</span> <span class="token punctuation">{</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #999<span class="token punctuation">;</span>
        <span class="token property">margin-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token selector">.edit</span> <span class="token punctuation">{</span>
      <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 22px<span class="token punctuation">;</span>
      <span class="token property">width</span><span class="token punctuation">:</span> 52px<span class="token punctuation">;</span>
      <span class="token property">line-height</span><span class="token punctuation">:</span> 22px<span class="token punctuation">;</span>
      <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token property">color</span><span class="token punctuation">:</span> #DE644B<span class="token punctuation">;</span>
      <span class="token property">border-radius</span><span class="token punctuation">:</span> 11px<span class="token punctuation">;</span>
      <span class="token property">border</span><span class="token punctuation">:</span> 1px solid #DE644B<span class="token punctuation">;</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
      <span class="token selector">&amp;.active</span> <span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> #DE644B<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.body</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 6px 0 16px<span class="token punctuation">;</span>
    <span class="token selector">a</span> <span class="token punctuation">{</span>
      <span class="token property">display</span><span class="token punctuation">:</span> inline<span class="token operator">-</span>block<span class="token punctuation">;</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 0 8px<span class="token punctuation">;</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span>14px<span class="token punctuation">;</span>
      <span class="token property">color</span><span class="token punctuation">:</span> #3A3948<span class="token punctuation">;</span>
      <span class="token property">background</span><span class="token punctuation">:</span> #F7F8FA<span class="token punctuation">;</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 36px<span class="token punctuation">;</span>
      <span class="token property">line-height</span><span class="token punctuation">:</span> 36px<span class="token punctuation">;</span>
      <span class="token property">min-width</span><span class="token punctuation">:</span> 78px<span class="token punctuation">;</span>
      <span class="token property">margin-right</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
      <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
      <span class="token property">border-radius</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span>
      <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token selector">&amp;.active</span> <span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">@geek-color</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>了解动态修改的类名</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>1. 编辑按钮----点击后----&gt;完成按钮，需要加上active类名
2. 我的频道按钮，如果是当前浏览频道，需要加上active类名
</code></pre></div><p><strong>总结：</strong> 准备好布局，知道 active 类名的作用。</p> <h3 id="_03-频道-渲染我的频道"><a href="#_03-频道-渲染我的频道" class="header-anchor">#</a> 03-频道-渲染我的频道</h3> <blockquote><p>目的：完成我的频道渲染与激活当前浏览频道。</p></blockquote> <p>大致步骤：</p> <ul><li>完成我的频道渲染，数据从首页组件传入。</li> <li>完成当前浏览频道激活，首页组件准备当前浏览频道索引，传人数据给频道组件</li></ul> <p>落地代码：</p> <ul><li>完成我的频道渲染，数据从首页组件传入。</li></ul> <p><code>src/views/home/index.vue</code>  传入我的频道数据</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 频道 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;article-channel
</span><span class="token prefix unchanged"> </span><span class="token line">     v-model=&quot;showChannel&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      :myChannels=&quot;myChannels&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/article-channel&gt;
</span></span></code></pre></div><p><code>src/views/home/components/article-channel.vue</code>  使用我的频道数据</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> props: {
</span><span class="token prefix unchanged"> </span><span class="token line">   value: {
</span><span class="token prefix unchanged"> </span><span class="token line">     type: Boolean,
</span><span class="token prefix unchanged"> </span><span class="token line">     default: false
</span><span class="token prefix unchanged"> </span><span class="token line">   },
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    myChannels: {
</span><span class="token prefix inserted">+</span><span class="token line">      type: Array,
</span><span class="token prefix inserted">+</span><span class="token line">      default: () =&gt; []
</span><span class="token prefix inserted">+</span><span class="token line">    }
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;head&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;h3&gt;我的频道&lt;small&gt;点击进入频道&lt;/small&gt;&lt;/h3&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;a class=&quot;edit&quot; href=&quot;javascript:;&quot;&gt;编辑&lt;/a&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;body&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        &lt;a
</span><span class="token prefix inserted">+</span><span class="token line">          href=&quot;javascript:;&quot;
</span><span class="token prefix inserted">+</span><span class="token line">          v-for=&quot;(item,i) in myChannels&quot;
</span><span class="token prefix inserted">+</span><span class="token line">          :key=&quot;item.id&quot;
</span><span class="token prefix inserted">+</span><span class="token line">        &gt;
</span><span class="token prefix inserted">+</span><span class="token line">          {{item.name}}
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;/a&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span></span></code></pre></div><ul><li>完成当前浏览频道激活，首页组件准备当前浏览频道索引，传人数据给频道组件。</li></ul> <p><code>src/views/home/index.vue</code> 浏览频道索引，传给频道组件</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     myChannels: [],
</span><span class="token prefix unchanged"> </span><span class="token line">     showChannel: false,
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      activeIndex: 0
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    &lt;van-tabs animated v-model=&quot;activeIndex&quot;&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-tab :key=&quot;item.id&quot; v-for=&quot;item in myChannels&quot; :title=&quot;item.name&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;article-list :channelId=&quot;item.id&quot;&gt;&lt;/article-list&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/van-tab&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-tabs&gt;
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 频道 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;article-channel
</span><span class="token prefix unchanged"> </span><span class="token line">     v-model=&quot;showChannel&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      :activeIndex=&quot;activeIndex&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     :myChannels=&quot;myChannels&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">   &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/article-channel&gt;
</span></span></code></pre></div><p><code>src/views/home/components/article-channel.vue</code>  使用浏览频道索引</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> props: {
</span><span class="token prefix unchanged"> </span><span class="token line">   value: {
</span><span class="token prefix unchanged"> </span><span class="token line">     type: Boolean,
</span><span class="token prefix unchanged"> </span><span class="token line">     default: false
</span><span class="token prefix unchanged"> </span><span class="token line">   },
</span><span class="token prefix unchanged"> </span><span class="token line">   myChannels: {
</span><span class="token prefix unchanged"> </span><span class="token line">     type: Array,
</span><span class="token prefix unchanged"> </span><span class="token line">     default: () =&gt; []
</span><span class="token prefix unchanged"> </span><span class="token line">   },
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    activeIndex: {
</span><span class="token prefix inserted">+</span><span class="token line">      type: Number,
</span><span class="token prefix inserted">+</span><span class="token line">      default: 0
</span><span class="token prefix inserted">+</span><span class="token line">    }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;head&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;h3&gt;我的频道&lt;small&gt;点击进入频道&lt;/small&gt;&lt;/h3&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;a class=&quot;edit&quot; href=&quot;javascript:;&quot;&gt;编辑&lt;/a&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;body&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;a
</span><span class="token prefix unchanged"> </span><span class="token line">         href=&quot;javascript:;&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">          :class=&quot;{active:activeIndex===i}&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">         v-for=&quot;(item,i) in myChannels&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         :key=&quot;item.id&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">         {{item.name}}
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;/a&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span></span></code></pre></div><p><strong>总结：</strong>  我的频道和当前浏览频道索引均在首页组件，准备好之后传递给频道组件，使用即可。</p> <h3 id="_04-频道-渲染可选频道"><a href="#_04-频道-渲染可选频道" class="header-anchor">#</a> 04-频道-渲染可选频道</h3> <blockquote><p>目的：完成可选频道的渲染</p></blockquote> <p>大致步骤：</p> <ul><li>知道可选频道数据：就是所有频道除去我的频道剩余频道。</li> <li>获取所有频道数据</li> <li>使用计算属性得到可选频道数据</li> <li>进行数据渲染即可</li></ul> <p>落地代码：<code>src/views/home/components/article-channel.vue</code></p> <ul><li>获取所有频道数据</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      allChannels<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getAllChannels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token function">getAllChannels</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getAllChannels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>allChannels <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>results
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><ul><li>使用计算属性得到可选频道数据</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>  computed<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// 可选频道</span>
    <span class="token function">optionalChannels</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 在myChannels中找不到的就是可选的</span>
      <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>allChannels<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=&gt;</span> <span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>myChannels<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token parameter">c</span> <span class="token operator">=&gt;</span> c<span class="token punctuation">.</span>id <span class="token operator">===</span> item<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>进行数据渲染即可</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>head<span class="token punctuation">&quot;</span></span> <span class="token style-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token style language-css"><span class="token property">margin-top</span><span class="token punctuation">:</span>12px</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span><span class="token punctuation">&gt;</span></span>频道推荐<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>body<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>javascript:;<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item in optionalChannels<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>+ {{item.name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong> 使用计算属性，全部频道-我的频道=可选频道。</p> <h3 id="_05-频道-点击进入频道"><a href="#_05-频道-点击进入频道" class="header-anchor">#</a> 05-频道-点击进入频道</h3> <blockquote><p>目的：频道组件点击频道，关闭频道对话框，首页切换到对应频道。技术点掌握sync的使用。</p></blockquote> <p>大致步骤：</p> <ul><li>点击频道将当前的点击按钮索引传递给父组件，父组件接收后修改tabs的值即可完成切换</li> <li>如果传给父组件的事件时 update:属性名称，父组件传值 :属性名称。可以简写 <code>属性名称.sync</code></li></ul> <p>落地代码：</p> <ul><li>完成点击进入频道功能</li></ul> <p><code>src/views/home/components/article-channel.vue</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &lt;a
</span><span class="token prefix unchanged"> </span><span class="token line">         href=&quot;javascript:;&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         :class=&quot;{active:activeIndex===i}&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         v-for=&quot;(item,i) in myChannels&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         :key=&quot;item.id&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">          @click=&quot;enterChannel(i)&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &gt;
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 进入频道</span>
    <span class="token function">enterChannel</span> <span class="token punctuation">(</span><span class="token parameter">index</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 关闭对话框</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$emit</span><span class="token punctuation">(</span><span class="token string">'input'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
      <span class="token comment">// 传递频道索引</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$emit</span><span class="token punctuation">(</span><span class="token string">'update:activeIndex'</span><span class="token punctuation">,</span> index<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p><code>src/views/home/index.vue</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 频道 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;article-channel
</span><span class="token prefix unchanged"> </span><span class="token line">     v-model=&quot;showChannel&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">     :myChannels=&quot;myChannels&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">     :activeIndex=&quot;activeIndex&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      @update:activeIndex=&quot;activeIndex=$event&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/article-channel&gt;
</span></span></code></pre></div><ul><li><code>.sync</code> 也是一个语法糖，可以简写 <code>:abc=&quot;数据&quot;</code> <code>@update:abc=&quot;数据=$event&quot;</code>  代码，其实这段代码就是实现了双向数据绑定，但是组件不能使用多个<code>v-model</code>，所以提供了 <code>.sync</code> 来简写代码。</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 频道 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;article-channel
</span><span class="token prefix unchanged"> </span><span class="token line">     v-model=&quot;showChannel&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">     :myChannels=&quot;myChannels&quot;
</span></span><span class="token deleted-sign deleted"><span class="token prefix deleted">-</span><span class="token line">      :activeIndex=&quot;activeIndex&quot;
</span><span class="token prefix deleted">-</span><span class="token line">      @update:activeIndex=&quot;activeIndex=$event&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      :activeIndex.sync=&quot;activeIndex&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/article-channel&gt;
</span></span></code></pre></div><p><strong>总结：</strong> 知道 <code>.sync</code> 语法糖作用和简写代码的规则，<code>:abc=&quot;数据&quot;</code> <code>@update:abc=&quot;数据=$event&quot;</code> 。</p> <h3 id="_06-频道-支持本地操作"><a href="#_06-频道-支持本地操作" class="header-anchor">#</a> 06-频道-支持本地操作</h3> <blockquote><p>目的：未登录情况下获取我的频道都是写死的，服务端未提供修改接口，需要本地存储，本地修改。</p></blockquote> <p><img src="/document/assets/img/1625817617182.6c9cd73b.png" alt="1625817617182"></p> <p>大致步骤：</p> <ul><li>按照流程图在 原来的API函数实现</li> <li>修改home组件中调用API函数的地方(因为数据结构会有变化)</li></ul> <p>落地代码：</p> <ul><li>按照流程图在 原来的API函数实现</li></ul> <p><code>src/api/channel.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取我的频道（未登录会返回默认的一些频道）
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getMyChannels</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> localData <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token constant">KEY</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token string">'[]'</span><span class="token punctuation">)</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>localData<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 保持和res一样的结构，使用这个API的地方就无需修改</span>
      <span class="token keyword">return</span> localData
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
      <span class="token comment">// 获取数据本地缓存</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/user/channels'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token comment">// 只存数组</span>
      localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token constant">KEY</span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>channels<span class="token punctuation">)</span><span class="token punctuation">)</span>
      <span class="token keyword">return</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>channels
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'v1_0/user/channels'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>channels
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>修改home组件中调用API函数的地方</li></ul> <p><code>src/views/home/index.vue</code></p> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 不使用err不写err即可，但是,号需要写</span>
    <span class="token keyword">const</span> channels <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getMyChannels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels <span class="token operator">=</span> channels
  <span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong> 在API函数完成获取我的频道逻辑业务，降低组件的业务复杂的，提高可复用性。</p> <p><strong>补充：</strong> 登录状态的切换，需要更新频道数据。</p> <div class="language-js extra-class"><pre class="language-js"><code>  watch<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token string">'$store.state.user.token'</span><span class="token operator">:</span> <span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> channels <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getMyChannels</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels <span class="token operator">=</span> channels
      <span class="token keyword">this</span><span class="token punctuation">.</span>activeIndex <span class="token operator">=</span> <span class="token number">0</span>  
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><h3 id="_07-频道-添加"><a href="#_07-频道-添加" class="header-anchor">#</a> 07-频道-添加</h3> <blockquote><p>目的：完成我的频道的添加操作，支持本地和线上。</p></blockquote> <p><img src="/document/assets/img/1625819871732.6ce6e79a.png" alt="1625819871732"></p> <p>大致步骤：</p> <ul><li>按照流程图 定义API函数实现</li> <li>绑定点击事件，调用API函数添加</li></ul> <p>落地代码：</p> <p><code>api/channel.js</code>   API函数</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 添加频道
 * @param {Array&lt;object&gt;} myChannels - 我的频道集合
 * @param {Number} myChannels.id - 频道ID
 * @param {String} myChannels.name - 频道名称
 * @param {Number} myChannels.seq - 频道名称
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">addChannel</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">myChannels</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 1. 获取本地</span>
    <span class="token keyword">const</span> localData <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token constant">KEY</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token string">'[]'</span><span class="token punctuation">)</span>
    <span class="token comment">// 2. 最后一项就是需要更新的</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> id<span class="token punctuation">,</span> name <span class="token punctuation">}</span> <span class="token operator">=</span> myChannels<span class="token punctuation">[</span>myChannels<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span>
    <span class="token comment">// 3. 追加新频道</span>
    localData<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token punctuation">,</span> name <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token comment">// 4. 存储本地</span>
    localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token constant">KEY</span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>localData<span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/user/channels'</span><span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'put'</span><span class="token punctuation">,</span>
      data<span class="token operator">:</span> <span class="token punctuation">{</span> channels<span class="token operator">:</span> myChannels <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><code>views/home/components/article-channel.vue</code>  添加频道</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;head&quot; style=&quot;margin-top:12px&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;h3&gt;频道推荐&lt;/h3&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;body&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        &lt;a @click=&quot;addChannel(item)&quot; href=&quot;javascript:;&quot; v-for=&quot;item in optionalChannels&quot; :key=&quot;item.id&quot;&gt;+ {{item.name}}&lt;/a&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 添加频道</span>
    <span class="token keyword">async</span> <span class="token function">addChannel</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 1. 使用重置式添加频道数据，准备重置式的数据</span>
      <span class="token keyword">const</span> newMyChannels <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">c<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          newMyChannels<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
            id<span class="token operator">:</span> c<span class="token punctuation">.</span>id<span class="token punctuation">,</span>
            name<span class="token operator">:</span> c<span class="token punctuation">.</span>name<span class="token punctuation">,</span>
            seq<span class="token operator">:</span> i
          <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
      newMyChannels<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token operator">...</span>item<span class="token punctuation">,</span> seq<span class="token operator">:</span> newMyChannels<span class="token punctuation">.</span>length <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token comment">// 2. 去做添加频道操作</span>
      <span class="token keyword">await</span> <span class="token function">addChannel</span><span class="token punctuation">(</span>newMyChannels<span class="token punctuation">)</span>
      <span class="token comment">// 3. 成功：更新我的频道</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong>  再添加频道到API函数处理登录和未登录的添加操作，使用重置的方式更新我的频道，需要再点击添加频道按钮后自己组织数据。</p> <h3 id="_08-频道-切换编辑"><a href="#_08-频道-切换编辑" class="header-anchor">#</a> 08-频道-切换编辑</h3> <blockquote><p>目的：显示删除按钮，完成编辑状态切换</p></blockquote> <p>大致步骤：</p> <ul><li>准备删除按钮</li> <li>切换编辑状态</li></ul> <p>落地代码：</p> <ul><li>切换编辑 <code>src/views/home/article-channel.vue</code></li></ul> <p>准备删除按钮（编辑状态，不是推荐，不是当前激活频道，才可以显示）</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> .body {
</span><span class="token prefix unchanged"> </span><span class="token line">   padding: 0 6px 0 16px;
</span><span class="token prefix unchanged"> </span><span class="token line">   a {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      position: relative;
</span><span class="token prefix inserted">+</span><span class="token line">      .geek-icon {
</span><span class="token prefix inserted">+</span><span class="token line">        position: absolute;
</span><span class="token prefix inserted">+</span><span class="token line">        top: -5px;
</span><span class="token prefix inserted">+</span><span class="token line">        right: -5px;
</span><span class="token prefix inserted">+</span><span class="token line">        line-height: 1;
</span><span class="token prefix inserted">+</span><span class="token line">      }
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &lt;a
</span><span class="token prefix unchanged"> </span><span class="token line">         href=&quot;javascript:;&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         :class=&quot;{active:activeIndex===i}&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         v-for=&quot;(item,i) in myChannels&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         :key=&quot;item.id&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         @click=&quot;enterChannel(i)&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       &gt;
</span><span class="token prefix unchanged"> </span><span class="token line">         {{item.name}}
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">          &lt;geek-icon v-show=&quot;isEdit &amp;&amp; i!==0 &amp;&amp; i!== activeIndex&quot; name=&quot;tag-close&quot;&gt;&lt;/geek-icon&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &lt;/a&gt;
</span></span></code></pre></div><p>切换编辑状态（关闭弹出层后，需要改成不编辑状态）</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;div class=&quot;head&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;h3&gt;我的频道&lt;small&gt;点击进入频道&lt;/small&gt;&lt;/h3&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        &lt;a class=&quot;edit&quot; @click=&quot;isEdit=!isEdit&quot; href=&quot;javascript:;&quot; :class=&quot;{active:isEdit}&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">          {{isEdit?'完成':'编辑'}}
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;/a&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 全部频道
</span><span class="token prefix unchanged"> </span><span class="token line">     allChannels: [],
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      // 是否编辑
</span><span class="token prefix inserted">+</span><span class="token line">      isEdit: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &lt;van-popup
</span><span class="token prefix unchanged"> </span><span class="token line">   :value=&quot;value&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">   @click-close-icon=&quot;$emit('input', false)&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">   closeable
</span><span class="token prefix unchanged"> </span><span class="token line">   position=&quot;left&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    @closed=&quot;isEdit=false&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> &gt;
</span></span></code></pre></div><h3 id="_09-频道-删除"><a href="#_09-频道-删除" class="header-anchor">#</a> 09-频道-删除</h3> <blockquote><p>目的：完成我的频道的删除操作，支持本地和线上。</p></blockquote> <p><img src="/document/assets/img/1625821170546.9341d839.png" alt="1625821170546"></p> <p>大致步骤：</p> <ul><li>按照流程图 定义API函数实现</li> <li>绑定点击事件，调用API函数删除</li></ul> <p>落地代码：</p> <ul><li>API函数 <code>api/channel.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 删除频道
 * @param {Number} id - 频道ID
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">delChannel</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 1. 获取本地</span>
    <span class="token keyword">const</span> localData <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token constant">KEY</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token string">'[]'</span><span class="token punctuation">)</span>
    <span class="token comment">// 2. 删除频道</span>
    <span class="token keyword">const</span> index <span class="token operator">=</span> localData<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=&gt;</span> item<span class="token punctuation">.</span>id <span class="token operator">===</span> id<span class="token punctuation">)</span>
    localData<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token comment">// 3. 存储本地</span>
    localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token constant">KEY</span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>localData<span class="token punctuation">)</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/user/channels/'</span> <span class="token operator">+</span> id<span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'delete'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>删除频道 <code>views/home/components/article.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token comment">&lt;!-- 给组件绑定click事件被认为是自定义事件不会被点击触发，需要加载native表示绑定的是原生事件，需要加上stop阻止事件冒泡触发进入频道的点击 --&gt;</span>
&lt;geek-icon @click.native.stop=&quot;delChannel(item.id)&quot;
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 删除频道</span>
    <span class="token keyword">async</span> <span class="token function">delChannel</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 删除操作</span>
      <span class="token keyword">await</span> <span class="token function">delChannel</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span>
      <span class="token comment">// 成功：更新我的频道</span>
      <span class="token keyword">const</span> index <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span><span class="token parameter">item</span> <span class="token operator">=&gt;</span> item<span class="token punctuation">.</span>id <span class="token operator">===</span> id<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>myChannels<span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><h2 id="第六章-文章详情"><a href="#第六章-文章详情" class="header-anchor">#</a> 第六章：文章详情</h2> <h3 id="_01-文章详情-顶部导航"><a href="#_01-文章详情-顶部导航" class="header-anchor">#</a> 01-文章详情-顶部导航</h3> <blockquote><p>目的：完成文章详情布局，顶部导航</p></blockquote> <p>大致步骤：</p> <ul><li>完成跳转</li> <li>顶部导航</li></ul> <p>落地代码：</p> <ul><li>完成跳转  <code>src/views/home/components/article-item.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-item van-hairline--bottom<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$router.push(<span class="token punctuation">'</span>/article?id=<span class="token punctuation">'</span>+article.art_id)<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>顶部导航</li></ul> <p><code>src/views/article/index.vue</code>   点击返回按钮回退历史，固定定位，右侧按钮通过right插槽使用，全局样式按钮黑色</p> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-nav-bar</span> <span class="token attr-name">left-arrow</span> <span class="token attr-name">@click-left</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$router.back()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">fixed</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#right</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>ellipsis<span class="token punctuation">&quot;</span></span> <span class="token attr-name">size</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>5.4vw<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-icon</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-nav-bar</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><code>src/assets/styles/index.less</code></p> <div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">// 全局生效的样式
.van-nav-bar .van-icon</span><span class="token punctuation">{</span>
  <span class="token property">color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><code>src/main.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token string">'@/assets/styles/index.less'</span>
</code></pre></div><h3 id="_02-文章详情-主体内容"><a href="#_02-文章详情-主体内容" class="header-anchor">#</a> 02-文章详情-主体内容</h3> <blockquote><p>目的：完成文章详情布局，标题，时间，作者，内容</p></blockquote> <p>大致步骤：</p> <ul><li>使用基础结构</li> <li>了解结构划分</li></ul> <p>落地代码：</p> <p><code>src/views/article/index.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 文章主体 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-wrapper<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 头部：标题 时间 作者 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>header<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>第二十二节：Java语言基础-详细讲解位运算符与流程控制语句<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>time<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>2019年03月11日<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>1186 阅读<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>61 评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>author van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span>
              <span class="token attr-name">round</span>
              <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span>
              <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span>
              <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://img01.yzcdn.cn/vant/cat.jpeg<span class="token punctuation">&quot;</span></span>
            <span class="token punctuation">/&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>黑马先锋<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-button</span> <span class="token attr-name">round</span> <span class="token attr-name">size</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>small<span class="token punctuation">&quot;</span></span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>#FC6627<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>+关注<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-button</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 内容：文章内容 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>main<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>html<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i in 10<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>我会把书籍分成两类,一类是全面型,一类是犀利型.前面介绍了一本全面型的书籍,接下来介绍的这本的特点是非常犀利,这类书籍的特点是作者能找对重点(2/8原则掌握的很好),在重点位置深入挖掘.这本书的作者John Resig也是JQuery的作者,他显然是个足够犀利的人儿.JQuery从未承诺解决所有问题,但再一些重点部位的突破,让这个类库如此流行.这本书并没有着重介绍JQuery,还是基于原生的JavaScript和DOM API.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span> 
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>space<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>  
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 评论：评论组件 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">.article-wrapper</span> <span class="token punctuation">{</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">overflow-y</span><span class="token punctuation">:</span> auto<span class="token punctuation">;</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 44px 0 50px<span class="token punctuation">;</span>
  <span class="token comment">// 头部</span>
  <span class="token selector">.header</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 16px<span class="token punctuation">;</span>  
    <span class="token selector">.title</span> <span class="token punctuation">{</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
      <span class="token property">font-weight</span><span class="token punctuation">:</span> normal<span class="token punctuation">;</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 10px 0<span class="token punctuation">;</span>
      <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token selector">.time</span> <span class="token punctuation">{</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
      <span class="token property">color</span><span class="token punctuation">:</span> #999<span class="token punctuation">;</span>
      <span class="token selector">span:nth-child(2n)</span> <span class="token punctuation">{</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> 0 5px<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token property">top</span><span class="token punctuation">:</span> <span class="token operator">-</span>1px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token selector">.author</span> <span class="token punctuation">{</span>
      <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
      <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 10px 0 <span class="token punctuation">;</span>
      <span class="token selector">.name</span> <span class="token punctuation">{</span>
        <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
        <span class="token property">padding-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// 内容</span>
  <span class="token selector">.main</span> <span class="token punctuation">{</span>
    <span class="token selector">.space</span> <span class="token punctuation">{</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
      <span class="token property">background</span><span class="token punctuation">:</span> <span class="token variable">@geek-gray-color</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token selector">.html</span> <span class="token punctuation">{</span>
      <span class="token property">word-break</span><span class="token punctuation">:</span> break<span class="token operator">-</span>all<span class="token punctuation">;</span>
      <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
      <span class="token property">overflow</span><span class="token punctuation">:</span> hidden<span class="token punctuation">;</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 20px 16px<span class="token punctuation">;</span>
      <span class="token selector">/deep/ img</span> <span class="token punctuation">{</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span>100%<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> #f9f9f9<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">/deep/ pre</span> <span class="token punctuation">{</span>
        <span class="token property">white-space</span><span class="token punctuation">:</span> pre<span class="token operator">-</span>wrap<span class="token punctuation">;</span>
        <span class="token selector">code</span> <span class="token punctuation">{</span>
          <span class="token property">white-space</span><span class="token punctuation">:</span> pre<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><code>src/assets/styles/index.less</code></p> <div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">*</span> <span class="token punctuation">{</span>
  <span class="token property">box-sizing</span><span class="token punctuation">:</span> border<span class="token operator">-</span>box<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>总结：</strong> article-wrapper容器装：header  main  comment组件</p> <h3 id="_03-文章详情-渲染页面"><a href="#_03-文章详情-渲染页面" class="header-anchor">#</a> 03-文章详情-渲染页面</h3> <blockquote><p>目的：获取文章详情数据进行渲染   <em>7974 这个文章数据不错哦</em></p></blockquote> <p>大致步骤：</p> <ul><li>定义API接口函数</li> <li>定义数据，获取数据</li> <li>渲染页面</li></ul> <p>落地代码：</p> <ul><li>定义API接口函数  <code>src/api/article.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取文章详情
 * @param {String} id - 文章ID
 * @returns
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getArticle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/articles/'</span> <span class="token operator">+</span> id
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>定义数据，获取数据 <code>src/views/article/index.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getArticle <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/article'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticlePage'</span><span class="token punctuation">,</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      article<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getArticle</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token function">getArticle</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getArticle</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>$route<span class="token punctuation">.</span>query<span class="token punctuation">.</span>id<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>article <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>渲染页面 <code>src/views/article/index.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 文章主体 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-wrapper<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 头部：标题 时间 作者 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>header<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{article.title}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>time<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.pubdate}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.read_count}} 阅读<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>|<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.comm_count}} 评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>author van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.aut_photo<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{article.aut_name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-button</span> <span class="token attr-name">round</span> <span class="token attr-name">size</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>small<span class="token punctuation">&quot;</span></span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>#FC6627<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>+ 关注<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-button</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 内容：文章内容 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>main<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>html<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-html</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.content<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>space<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 评论：评论组件 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong>  富文本内容使用v-html渲染</p> <h3 id="_04-文章详情-导航交互"><a href="#_04-文章详情-导航交互" class="header-anchor">#</a> 04-文章详情-导航交互</h3> <blockquote><p>目的：完成在滚动页面时候，头部被卷起后，在顶部导航显示作者信息。</p></blockquote> <p>大致步骤：</p> <ul><li>准备顶部导航作者信息</li> <li>监听滚动，显示隐藏作者信息</li></ul> <p>落地代码：</p> <ul><li>准备顶部导航作者信息 <code>src/views/article/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 导航 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;van-nav-bar left-arrow @click-left=&quot;$router.back()&quot; fixed&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;template #title&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;div class=&quot;nav-author&quot;&gt;
</span><span class="token prefix inserted">+</span><span class="token line">          &lt;van-image round width=&quot;7vw&quot; height=&quot;7vw&quot; :src=&quot;article.aut_photo&quot;/&gt;
</span><span class="token prefix inserted">+</span><span class="token line">          &lt;span class=&quot;name&quot;&gt;{{article.aut_name}}&lt;/span&gt;
</span><span class="token prefix inserted">+</span><span class="token line">          &lt;span class=&quot;line&quot;&gt;|&lt;/span&gt;
</span><span class="token prefix inserted">+</span><span class="token line">          &lt;span class=&quot;follow&quot;&gt;关注&lt;/span&gt;
</span><span class="token prefix inserted">+</span><span class="token line">        &lt;/div&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;/template&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;template #right&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;van-icon name=&quot;ellipsis&quot; size=&quot;5.4vw&quot;&gt;&lt;/van-icon&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/template&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-nav-bar&gt;
</span></span></code></pre></div><div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">/deep/ .van-nav-bar__title</span> <span class="token punctuation">{</span>
   <span class="token property">max-width</span><span class="token punctuation">:</span> 270px<span class="token punctuation">;</span>
   <span class="token property">width</span><span class="token punctuation">:</span> 270px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.nav-author</span> <span class="token punctuation">{</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">justify-content</span><span class="token punctuation">:</span> flex<span class="token operator">-</span>start<span class="token punctuation">;</span>
  <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
  <span class="token selector">&gt; span</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
    <span class="token property">padding-left</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.line</span> <span class="token punctuation">{</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span>
    <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> <span class="token operator">-</span>1px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.follow</span> <span class="token punctuation">{</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">@geek-color</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>监听滚动，显示隐藏作者信息  <code>src/views/article/index.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 文章主体 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-wrapper<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>wrapper<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@scroll</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>onScroll<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 头部：标题 时间 作者 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>header<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>header<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      article<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
      showNavAuthor<span class="token operator">:</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// 监听滚动</span>
    <span class="token function">onScroll</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> scrollTop <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>wrapper<span class="token punctuation">.</span>scrollTop
      <span class="token keyword">const</span> headerHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>header<span class="token punctuation">.</span>offsetHeight
      <span class="token keyword">this</span><span class="token punctuation">.</span>showNavAuthor <span class="token operator">=</span> scrollTop <span class="token operator">&gt;</span> headerHeight
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">#title</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>nav-author<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-show</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showNavAuthor<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>总结：</strong>  通过ref获取wrapper的卷起高度 比较  header的高度，大于就显示头部导航的作者信息</p> <h3 id="_05-文章详情-关注作者"><a href="#_05-文章详情-关注作者" class="header-anchor">#</a> 05-文章详情-关注作者</h3> <blockquote><p>目的：完成关注作者和取消关注功能</p></blockquote> <p>大致步骤：</p> <ul><li>定义关注作者和取消关注的API接口函数</li> <li>绑定点击事件，完成关注和取消关注操作</li> <li>切换关注按钮的显示</li></ul> <p>落地代码：</p> <ul><li>API接口函数  <code>src/api/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 关注 和 取消关注
 * @param {*} authorId - 作者ID
 * @param {*} isFollow - 是否关注
 * @returns Promise
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">followAuthor</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">authorId<span class="token punctuation">,</span> isFollow</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>isFollow<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/user/followings'</span><span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span>
      data<span class="token operator">:</span> <span class="token punctuation">{</span> target<span class="token operator">:</span> authorId <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/user/followings/'</span> <span class="token operator">+</span> authorId<span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'delete'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>组件中处理：关注 和 取消关注   <code>src/views/article/index.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 关注&amp;取消关注</span>
    <span class="token keyword">async</span> <span class="token function">followAuthor</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> newStatus <span class="token operator">=</span> <span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>is_followed
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">followAuthor</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>aut_id<span class="token punctuation">,</span> newStatus<span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'操作失败'</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span>newStatus <span class="token operator">?</span> <span class="token string">'关注成功'</span> <span class="token operator">:</span> <span class="token string">'取消关注'</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>is_followed <span class="token operator">=</span> newStatus
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>切换按钮</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>          <span class="token operator">&lt;</span>span @click<span class="token operator">=</span><span class="token string">&quot;followAuthor()&quot;</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;follow&quot;</span> <span class="token operator">:</span><span class="token keyword">class</span><span class="token operator">=</span><span class="token string">&quot;{un:article.is_followed}&quot;</span><span class="token operator">&gt;</span>
            <span class="token punctuation">{</span><span class="token punctuation">{</span>article<span class="token punctuation">.</span>is_followed<span class="token operator">?</span><span class="token string">'取消关注'</span><span class="token operator">:</span><span class="token string">'关注'</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
          <span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">&gt;</span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-button</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.is_followed<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>followAuthor()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">round</span> <span class="token attr-name">size</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>small<span class="token punctuation">&quot;</span></span> <span class="token punctuation">&gt;</span></span>取消关注<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-button</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-button</span> <span class="token attr-name">v-else</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>followAuthor()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">round</span> <span class="token attr-name">size</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>small<span class="token punctuation">&quot;</span></span> <span class="token attr-name">color</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>#FC6627<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>+ 关注<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-button</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> .follow {
</span><span class="token prefix unchanged"> </span><span class="token line">   color: @geek-color;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    // 不加&amp;  .follow .un   后代选择器
</span><span class="token prefix inserted">+</span><span class="token line">    // 加上&amp;  .follow.un    交集选择器
</span><span class="token prefix inserted">+</span><span class="token line">    &amp;.un {
</span><span class="token prefix inserted">+</span><span class="token line">      color: #999;
</span><span class="token prefix inserted">+</span><span class="token line">    }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span></code></pre></div><h3 id="_06-文章详情-骨架效果"><a href="#_06-文章详情-骨架效果" class="header-anchor">#</a> 06-文章详情-骨架效果</h3> <blockquote><p>目的：在文章加载过程中加上骨架效果</p></blockquote> <img src="" alt="1627201911906" style="zoom:50%;"> <p>大致步骤：</p> <ul><li>定义一个加载中状态数据</li> <li>再请求前改成加载中，请求后改成加载完成</li> <li>根据数据显示骨架效果</li></ul> <p>落地代码：  <code>src/views/article/index.vue</code></p> <ul><li>数据</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     article: {},
</span><span class="token prefix unchanged"> </span><span class="token line">     showNavAuthor: false,
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      loading: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><ul><li>状态设置</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   // 文章详情
</span><span class="token prefix unchanged"> </span><span class="token line">   async getArticle () {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      this.loading = true
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     const [, res] = await getArticle(this.$route.query.id)
</span><span class="token prefix unchanged"> </span><span class="token line">     this.article = res.data.data
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      this.loading = false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span></span></code></pre></div><ul><li>骨架效果</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 骨架组件 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>loading<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-skeleton<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-skeleton</span> <span class="token attr-name">title</span> <span class="token attr-name">:row</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>12<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 文章主体 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">v-else</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-wrapper<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>wrapper<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@scroll</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>onScroll<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">.article-skeleton</span> <span class="token punctuation">{</span>
  <span class="token property">padding-top</span><span class="token punctuation">:</span> 60px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_07-文章详情-代码高亮"><a href="#_07-文章详情-代码高亮" class="header-anchor">#</a> <strong>07-文章详情-代码高亮</strong></h3> <blockquote><p>目的：技术类文章，会有code标签写的代码，给代码加上高亮样式</p></blockquote> <img src="/document/assets/img/1627201877382.1097188f.png" alt="1627201877382" style="zoom:50%;"> <p>大致步骤：</p> <ul><li>安装 <code>highlight.js</code> 插件</li> <li>分析使用过程：先有html结构，使用插件给结构加样式。</li> <li>决定封装成指令</li></ul> <p>落地代码：</p> <ul><li>安装</li></ul> <div class="language-bash extra-class"><pre class="language-bash"><code><span class="token function">npm</span> i highlight.js@10.7.2
</code></pre></div><ul><li>使用分析</li></ul> <p>使用：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 文档结构加载完毕事件</span>
document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'DOMContentLoaded'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 找到所有的 pre 下的 code  标签</span>
  document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">'pre code'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 转化成代码结构的html标签</span>
    hljs<span class="token punctuation">.</span><span class="token function">highlightElement</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>风格：</p> <div class="language- extra-class"><pre class="language-text"><code>// 存放风格样式文件目录
geek-client-mobile\node_modules\highlight.js\styles
</code></pre></div><ul><li>指令封装 <code>src/components/index.js</code></li></ul> <p>由于是某一个标签内的结构需要加上样式需要操作dom，而且需要内容渲染完毕后去操作，使用指令比较合适。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> hljs <span class="token keyword">from</span> <span class="token string">'highlight.js'</span>
<span class="token keyword">import</span> <span class="token string">'highlight.js/styles/vs2015.css'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// install函数 定义全局指令</span>
    Vue<span class="token punctuation">.</span><span class="token function">directive</span><span class="token punctuation">(</span><span class="token string">'highlight'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">el</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> codeList <span class="token operator">=</span> el<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">'pre code'</span><span class="token punctuation">)</span>
      codeList<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">code</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        hljs<span class="token punctuation">.</span><span class="token function">highlightElement</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span> 
      <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><ul><li>使用指令   <code>src/views/article/index.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token comment">&lt;!-- 内容：文章内容 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>main<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-html</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.content<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-highlight</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>总结：使用自定义指令来实现代码高亮效果。</p> <h2 id="第七章-评论回复"><a href="#第七章-评论回复" class="header-anchor">#</a> 第七章：评论回复</h2> <h3 id="_01-文章评论-组件布局"><a href="#_01-文章评论-组件布局" class="header-anchor">#</a> 01-文章评论-组件布局</h3> <blockquote><p>目的：准备评论回复组件的基础布局结构，了解结构</p></blockquote> <img src="/document/assets/img/1627201821802.9a8a02fc.png" alt="1627201821802" style="zoom:67%;"> <p>大致步骤：</p> <ul><li>准备基础布局结构</li> <li>使用组件</li> <li>分析了解布局结构</li></ul> <p>落地代码：<code>src/views/article/components/article-comment.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article-comment<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 全部评论 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-sticky</span> <span class="token attr-name">offset-top</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>11.73333vw<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>全部评论 (0)<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>0 点赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-sticky</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 评论列表 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>list<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item van-hairline--bottom<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i in 10<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://img01.yzcdn.cn/vant/cat.jpeg<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>清风徐来<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>zan<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>0 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>like2<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cont<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>说的不错！<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>回复 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>van-icon van-icon-arrow<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>time<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>2小时内<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 底部工具 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticleComment'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.article-comment</span> <span class="token punctuation">{</span>
  <span class="token selector">.title</span> <span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">justify-content</span><span class="token punctuation">:</span> space-between<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 16px<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> #fff<span class="token selector">;
    span</span> <span class="token punctuation">{</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token selector">;
      &amp;:last-child</span> <span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.list</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 16px<span class="token selector">;
    .item</span> <span class="token punctuation">{</span>
      <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 10px 0<span class="token selector">;
      .info</span> <span class="token punctuation">{</span>
        <span class="token property">padding-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
        <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token selector">;
        p</span> <span class="token punctuation">{</span>
          <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token selector">;
          .name</span> <span class="token punctuation">{</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
          <span class="token punctuation">}</span>
          <span class="token selector">.zan</span> <span class="token punctuation">{</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
            <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span>
            <span class="token property">color</span><span class="token punctuation">:</span> #999<span class="token selector">;
            .geek-icon</span> <span class="token punctuation">{</span>
              <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
              <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
              <span class="token property">top</span><span class="token punctuation">:</span> -1px<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
          <span class="token punctuation">}</span>
          <span class="token selector">&amp;.cont</span> <span class="token punctuation">{</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
            <span class="token property">color</span><span class="token punctuation">:</span> #666<span class="token punctuation">;</span>
            <span class="token property">padding</span><span class="token punctuation">:</span> 10px 0<span class="token punctuation">;</span>
            <span class="token property">word-break</span><span class="token punctuation">:</span> break-all<span class="token punctuation">;</span>
            <span class="token property">padding-right</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
          <span class="token punctuation">}</span>
          <span class="token selector">.reply</span> <span class="token punctuation">{</span>
            <span class="token property">min-width</span><span class="token punctuation">:</span> 60px<span class="token punctuation">;</span>
            <span class="token property">height</span><span class="token punctuation">:</span> 24px<span class="token punctuation">;</span>
            <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
            <span class="token property">line-height</span><span class="token punctuation">:</span> 28px<span class="token punctuation">;</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
            <span class="token property">background</span><span class="token punctuation">:</span> <span class="token atrule"><span class="token rule">@geek-gray-color</span><span class="token punctuation">;</span></span>
            <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span>
            <span class="token property">border-radius</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
            <span class="token property">color</span><span class="token punctuation">:</span> #666<span class="token selector">;
            .van-icon</span> <span class="token punctuation">{</span>
              <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
              <span class="token property">top</span><span class="token punctuation">:</span> 1px<span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
          <span class="token punctuation">}</span>
          <span class="token selector">.time</span> <span class="token punctuation">{</span>
            <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
            <span class="token property">color</span><span class="token punctuation">:</span> #999<span class="token punctuation">;</span>
            <span class="token property">margin-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
          <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>使用组件 <code>src/views/article/index.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token comment">&lt;!-- 评论：评论组件 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-comment</span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> ArticleComment <span class="token keyword">from</span> <span class="token string">'./components/article-comment.vue'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'ArticlePage'</span><span class="token punctuation">,</span>
  components<span class="token operator">:</span> <span class="token punctuation">{</span> ArticleComment <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>分析了解布局结构</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>1. 全部评论，盒子需要滚动到顶部固定定位，使用van-sticky offset-top=&quot;11.73333vw&quot;
2. 评论列表，
3. 底部工具
</code></pre></div><h3 id="_02-文章评论-渲染列表"><a href="#_02-文章评论-渲染列表" class="header-anchor">#</a> 02-文章评论-渲染列表</h3> <blockquote><p>目的：完成文章评论列表上拉加载，渲染列表</p></blockquote> <p>大致步骤：</p> <ul><li>使用van-list组件完成上拉加载效果，初始化就加载一次</li> <li>定义API函数获取文章评论</li> <li>使用API函数获取数据，完成列表渲染</li></ul> <p>落地代码：</p> <ul><li>使用van-list组件完成上拉加载效果 <code>src/views/article/components/article-comment.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 评论列表 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;div class=&quot;list&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;van-list v-model=&quot;loading&quot; :finished=&quot;finished&quot; finished-text=&quot;没有评论了&quot; @load=&quot;onLoad&quot;&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &lt;div class=&quot;item van-hairline--bottom&quot; v-for=&quot;i in 10&quot; :key=&quot;i&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">         &lt;van-image round width=&quot;10vw&quot; height=&quot;10vw&quot; src=&quot;https://img01.yzcdn.cn/vant/cat.jpeg&quot;/&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">         &lt;div class=&quot;info&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">           &lt;p&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">             &lt;span class=&quot;name&quot;&gt;清风徐来&lt;/span&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">             &lt;span class=&quot;zan&quot;&gt;0 &lt;geek-icon name=&quot;like2&quot; /&gt;&lt;/span&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">           &lt;/p&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">           &lt;p class=&quot;cont&quot;&gt;说的不错！&lt;/p&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">           &lt;p&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">             &lt;span class=&quot;reply&quot;&gt;回复 &lt;i class=&quot;van-icon van-icon-arrow&quot;&gt;&lt;/i&gt;&lt;/span&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">             &lt;span class=&quot;time&quot;&gt;2小时内&lt;/span&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">           &lt;/p&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">         &lt;/div&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;/div&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;/van-list&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;/div&gt;
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      loading<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
      finished<span class="token operator">:</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function">onLoad</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'加载评论'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><ul><li>定义API函数获取文章评论 <code>src/api/article.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取文章评论
 * @param {String} articleId - 文章ID
 * @param {String} offset - 上一页数据最后一个ID，做为下一页请求的偏移量
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getCommentsByArticle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">articleId<span class="token punctuation">,</span> offset</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/comments'</span><span class="token punctuation">,</span>
    params<span class="token operator">:</span> <span class="token punctuation">{</span> type<span class="token operator">:</span> <span class="token string">'a'</span><span class="token punctuation">,</span> source<span class="token operator">:</span> articleId<span class="token punctuation">,</span> offset <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>使用API函数获取数据，完成列表渲染</li></ul> <p>传人文章对象 <code>src/views/article/index.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token comment">&lt;!-- 评论：评论组件 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-comment</span> <span class="token attr-name">:article</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><p>获取数据 <code>src/views/article/components/article-comment.vue</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getCommentsByArticle <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/articles'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      loading<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
      finished<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
      offset<span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span>
      comments<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token function">onLoad</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 获取数据</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getCommentsByArticle</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>art_id<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>offset<span class="token punctuation">)</span>
      <span class="token comment">// 这次数据最后一条ID和所有数据最后一条ID相同，没有数据了</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>last_id <span class="token operator">===</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>end_id<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 加载完毕</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">// 记录偏移量，为下次请求准备</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>offset <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>last_id
      <span class="token punctuation">}</span>
      <span class="token comment">// 追加评论数据</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>comments<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token operator">...</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>results<span class="token punctuation">)</span>
      <span class="token comment">// 结束加载状态</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>loading <span class="token operator">=</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><p>进行渲染列表  <code>src/views/article/components/article-comment.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code>        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item van-hairline--bottom<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item in comments<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.com_id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.aut_photo<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.aut_name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>zan<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.like_count}}
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.is_liking?<span class="token punctuation">'</span>like-sel<span class="token punctuation">'</span>:<span class="token punctuation">'</span>like2<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cont<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.content}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.reply_count}}回复 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>van-icon van-icon-arrow<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>time<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.pubdate|relativeTime}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>渲染总评数量</p> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>title van-hairline--bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>全部评论 ({{article.comm_count}})<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>{{article.like_count}} 点赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_03-文章评论-底部工具"><a href="#_03-文章评论-底部工具" class="header-anchor">#</a> 03-文章评论-底部工具</h3> <blockquote><p>目的：完成底部工具栏的布局和渲染。</p></blockquote> <img src="/document/assets/img/1627201770541.65df13c9.png" alt="1627201770541" style="zoom:67%;"> <p>大致步骤：</p> <ul><li>完成底部工具栏布局，了解结构和样式</li> <li>使用 article 完成渲染</li></ul> <p>落地代码： <code>src/views/article/components/article-comment.vue</code></p> <ul><li>工具栏结构</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 底部工具 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer van-hairline--top<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>van-icon van-icon-edit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>comment<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span><span class="token punctuation">&gt;</span></span>0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>like<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>点赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>collect<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>收藏<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>share<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>分享<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>工具栏样式</li></ul> <div class="language-less extra-class"><pre class="language-less"><code>    <span class="token selector">.footer</span> <span class="token punctuation">{</span>
    <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span>
    <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">bottom</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token selector">.input</span> <span class="token punctuation">{</span>
      <span class="token property">margin-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
      <span class="token property">width</span><span class="token punctuation">:</span> 200px<span class="token punctuation">;</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 34px<span class="token punctuation">;</span>
      <span class="token property">background</span><span class="token punctuation">:</span> <span class="token variable">@geek-gray-color</span><span class="token punctuation">;</span>
      <span class="token property">border-radius</span><span class="token punctuation">:</span> 17px<span class="token punctuation">;</span>
      <span class="token property">line-height</span><span class="token punctuation">:</span> 36px<span class="token punctuation">;</span>
      <span class="token property">padding-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
      <span class="token selector">.van-icon</span> <span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #999<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token selector">.btn</span> <span class="token punctuation">{</span>
      <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
      <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
      <span class="token selector">p</span> <span class="token punctuation">{</span>
        <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">.geek-icon</span> <span class="token punctuation">{</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 18px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">i</span> <span class="token punctuation">{</span>
        <span class="token property">height</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
        <span class="token property">min-width</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> 0 3px<span class="token punctuation">;</span>
        <span class="token property">background</span><span class="token punctuation">:</span> <span class="token variable">@geek-color</span><span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
        <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
        <span class="token property">right</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
        <span class="token property">top</span><span class="token punctuation">:</span> <span class="token operator">-</span>4px<span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> 8px<span class="token punctuation">;</span>
        <span class="token property">font-style</span><span class="token punctuation">:</span> normal<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
</code></pre></div><ul><li>完成渲染</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 底部工具 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer van-hairline--top<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>van-icon van-icon-edit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>comment<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>评论<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.comm_count<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{article.comm_count}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.attitude===1?<span class="token punctuation">'</span>like-sel<span class="token punctuation">'</span>:<span class="token punctuation">'</span>like<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>点赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.is_collected?<span class="token punctuation">'</span>collect-sel<span class="token punctuation">'</span>:<span class="token punctuation">'</span>collect<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>收藏<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>share<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>分享<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p><strong>注意：</strong>  attitude === 1 代表点赞，其他代表未点赞。可以通过dev-tools切换数据，测试状态。</p> <h3 id="_04-文章评论-传送功能"><a href="#_04-文章评论-传送功能" class="header-anchor">#</a> 04-文章评论-传送功能</h3> <blockquote><p>目的：评论按钮滚动到评论区，再次点击回到顶部。</p></blockquote> <img src="/document/assets/img/1627202278994.e4059cd4.png" alt="1627202278994" style="zoom:67%;"> <p>大致步骤：</p> <ul><li>分析：评论区位置 = 头部高度 + 内容高度 ， 组件初始化就需要<strong>加载评论</strong>。</li> <li><code>index.vue</code> 组件操作滚动方便，<code>article-wrapper</code>  是滚动容器</li> <li>点击评论按钮，触发自定义时间，父组件给 <code>article-commont</code> 绑定，进行切换位置</li></ul> <p>落地代码：</p> <ul><li>触发事件  <code>src/views/article/components/article-comment.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;div class=&quot;btn&quot; @click=&quot;$emit('click-comment')&quot;&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &lt;geek-icon name=&quot;comment&quot;&gt;&lt;/geek-icon&gt;&lt;p&gt;评论&lt;/p&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">       &lt;i v-if=&quot;article.comm_count&quot;&gt;{{article.comm_count}}&lt;/i&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/div&gt;
</span></span></code></pre></div><ul><li>绑定事件  <code>src/views/article/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     article: {},
</span><span class="token prefix unchanged"> </span><span class="token line">     showNavAuthor: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     loading: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 是否滚动到评论位置
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      toComment: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token comment">&lt;!-- 评论：评论组件 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>article-comment</span> <span class="token attr-name">:article</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click-comment</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>srollToComment<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token comment">&lt;!-- 内容：文章内容 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>main<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>main<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 滚动到评论</span>
    <span class="token function">srollToComment</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> headerHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>header<span class="token punctuation">.</span>offsetHeight
      <span class="token keyword">const</span> mainHeight <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>main<span class="token punctuation">.</span>offsetHeight
      <span class="token comment">// 是否滚动到评论，切换状态</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>toComment <span class="token operator">=</span> <span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>toComment
      <span class="token comment">// 来回切换</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>toComment<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>wrapper<span class="token punctuation">.</span>scrollTop <span class="token operator">=</span> headerHeight <span class="token operator">+</span> mainHeight
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>wrapper<span class="token punctuation">.</span>scrollTop <span class="token operator">=</span> <span class="token number">0</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>默认加载评论(否则页面下面没数据撑开高度，滚动不过去)  <code>src/views/article/components/article-comment.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code>  <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>	
    <span class="token comment">// 开启加载中效果  </span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>loading <span class="token operator">=</span> <span class="token boolean">true</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">onLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_05-文章评论-点赞"><a href="#_05-文章评论-点赞" class="header-anchor">#</a> 05-文章评论-点赞</h3> <blockquote><p>目的：对文章点赞，取消点赞。</p></blockquote> <p>大致步骤：</p> <ul><li>定义给文章点赞API</li> <li>绑定点击，完成点赞</li></ul> <p>落地代码：</p> <ul><li>API函数 <code>src/api/article.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 点赞文章，取消点赞
 * @param {String} articleId - 文章ID
 * @param {Boolean} isLike - 是否点赞
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">likeArticle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">articleId<span class="token punctuation">,</span> isLike</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>isLike<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/article/likings'</span><span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span>
      data<span class="token operator">:</span> <span class="token punctuation">{</span> target<span class="token operator">:</span> articleId <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/article/likings/'</span> <span class="token operator">+</span> articleId<span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'delete'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</code></pre></div><ul><li>处理逻辑 <code>src/views/article/components/article-comment.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>likeArticle<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.attitude===1?<span class="token punctuation">'</span>like-sel<span class="token punctuation">'</span>:<span class="token punctuation">'</span>like<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>点赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line"> import { getCommentsByArticle, likeArticle } from '@/api/articles'
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token function">likeArticle</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>attitude <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">likeArticle</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>art_id<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'操作失败'</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>attitude <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">likeArticle</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>art_id<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'操作失败'</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>attitude <span class="token operator">=</span> <span class="token number">1</span>
      <span class="token punctuation">}</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'操作成功'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_06-文章评论-收藏"><a href="#_06-文章评论-收藏" class="header-anchor">#</a> 06-文章评论-收藏</h3> <blockquote><p>目标：对文章收藏，取消收藏。</p></blockquote> <p>大致步骤：</p> <ul><li>定义给收藏文章API</li> <li>绑定点击，完成收藏</li></ul> <p>落地代码：</p> <ul><li>API函数 <code>src/api/article.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 收藏文章，取消收藏
 * @param {String} articleId - 文章ID
 * @param {Boolean} isCollect - 是否收藏
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">collectArticle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">articleId<span class="token punctuation">,</span> isCollect</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>isCollect<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/article/collections'</span><span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span>
      data<span class="token operator">:</span> <span class="token punctuation">{</span> target<span class="token operator">:</span> articleId <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      url<span class="token operator">:</span> <span class="token string">'/v1_0/article/collections/'</span> <span class="token operator">+</span> articleId<span class="token punctuation">,</span>
      method<span class="token operator">:</span> <span class="token string">'delete'</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>处理逻辑</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>collectArticle<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">:name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>article.is_collected?<span class="token punctuation">'</span>collect-sel<span class="token punctuation">'</span>:<span class="token punctuation">'</span>collect<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>收藏<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line"> import { getCommentsByArticle, likeArticle, collectArticle } from '@/api/articles'
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token keyword">async</span> <span class="token function">collectArticle</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">collectArticle</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>art_id<span class="token punctuation">,</span> <span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>is_collected<span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'操作失败'</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>is_collected <span class="token operator">=</span> <span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>is_collected
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'操作成功'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_07-评论回复-回复弹层"><a href="#_07-评论回复-回复弹层" class="header-anchor">#</a> 07-评论回复-回复弹层</h3> <blockquote><p>目的：完成点击回复按钮，弹出回复页面，完成页面布局。</p></blockquote> <img src="/document/assets/img/1627201611235.1ea19cfa.png" alt="1627201611235" style="zoom:50%;"> <p>大致步骤：</p> <ul><li><p>准备弹窗，点击回复切换</p></li> <li><p>完成头部，和底部</p></li> <li><p>完成回复列表</p></li></ul> <p>落地代码： <code>src/views/article/components/article-comment.vue</code></p> <ul><li>准备弹窗</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 回复弹层 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-popup</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply.open<span class="token punctuation">&quot;</span></span> <span class="token attr-name">position</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>right<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 头 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-nav-bar</span> <span class="token attr-name">left-arrow</span> <span class="token attr-name">@click-left</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply.open=false<span class="token punctuation">&quot;</span></span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>0条回复<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply-wrapper list<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token comment">&lt;!-- 列表 --&gt;</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item van-hairline--bottom<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i in 10<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://img01.yzcdn.cn/vant/cat.jpeg<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>清风徐来<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>zan<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>0 <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>like2<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cont<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>说的不错！<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>time<span class="token punctuation">&quot;</span></span> <span class="token style-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token style language-css"><span class="token property">margin-left</span><span class="token punctuation">:</span>0</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>2小时内<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token comment">&lt;!-- 底 --&gt;</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer van-hairline--top<span class="token punctuation">&quot;</span></span> <span class="token style-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token style language-css"><span class="token property">position</span><span class="token punctuation">:</span>static</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>input big<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>i</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>van-icon van-icon-edit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>i</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>collect<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>收藏<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>share<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>geek-icon</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>分享<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-popup</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   .input {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &amp;.big {
</span><span class="token prefix inserted">+</span><span class="token line">        width: 260px;
</span><span class="token prefix inserted">+</span><span class="token line">      }
</span></span>


// 最下面加如下样式
.van-popup {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> width: 100%;
</span><span class="token prefix unchanged"> </span><span class="token line"> height: 100%;
</span><span class="token prefix unchanged"> </span><span class="token line"> display: flex;
</span><span class="token prefix unchanged"> </span><span class="token line"> flex-direction: column;
</span></span>}
.reply-wrapper {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> width: 100%;
</span><span class="token prefix unchanged"> </span><span class="token line"> height: 100%;
</span><span class="token prefix unchanged"> </span><span class="token line"> overflow-y: auto;
</span></span>}
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     loading: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     finished: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     offset: null,
</span><span class="token prefix unchanged"> </span><span class="token line">     comments: [],
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">     // 回复业务需要的数据
</span><span class="token prefix inserted">+</span><span class="token line">      reply: {
</span><span class="token prefix inserted">+</span><span class="token line">        open: false
</span><span class="token prefix inserted">+</span><span class="token line">      }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><ul><li>点击回复打开</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>clickReply(item)<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token function">clickReply</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 打开评论弹窗</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>open <span class="token operator">=</span> <span class="token boolean">true</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_08-评论回复-列表渲染"><a href="#_08-评论回复-列表渲染" class="header-anchor">#</a> 08-评论回复-列表渲染</h3> <blockquote><p>目的：完成评论的回复列表数据获取和渲染</p></blockquote> <p>大致步骤：</p> <ul><li>编写获取回复列表API函数</li> <li>打开对话框记录当前被回复的评论信息对象,打开的时候，需要重置数据</li> <li>使用van-list加载数据，但是不能默认加载，当打开回复对话框</li></ul> <p>落地代码：</p> <ul><li>API函数 <code>src/api/article.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取评论回复
 * @param {String} commentId - 评论ID
 * @param {String} offset - 上一页数据最后一个ID，做为下一页请求的偏移量
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getReplysByComment</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">commentId<span class="token punctuation">,</span> offset</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/comments'</span><span class="token punctuation">,</span>
    params<span class="token operator">:</span> <span class="token punctuation">{</span> type<span class="token operator">:</span> <span class="token string">'c'</span><span class="token punctuation">,</span> source<span class="token operator">:</span> commentId<span class="token punctuation">,</span> offset <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>打开对话框  <code>src/views/article/components/article-comment.vue</code></li></ul> <p>1）准备数据</p> <div class="language-js extra-class"><pre class="language-js"><code>      <span class="token comment">// 回复业务需要的数据</span>
      currComments<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
      reply<span class="token operator">:</span> <span class="token punctuation">{</span>
        open<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
        loading<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
        finished<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
        offset<span class="token operator">:</span> <span class="token keyword">null</span><span class="token punctuation">,</span>
        list<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
      <span class="token punctuation">}</span>
</code></pre></div><p>2）打开组件</p> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token function">clickReply</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 记录当前评论</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>currComments <span class="token operator">=</span> item
      <span class="token comment">// 打开评论弹窗</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>open <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token comment">// 加载效果</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>loading <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token comment">// 重置加载完毕</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token comment">// 重置数据</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
      <span class="token comment">// 重置请求参数</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>offset <span class="token operator">=</span> <span class="token keyword">null</span>
      <span class="token comment">// 开启加载</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">loadReply</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-list</span> <span class="token attr-name">:immediate-check</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>false<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply.loading<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:finished</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply.finished<span class="token punctuation">&quot;</span></span> <span class="token attr-name">finished-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>没有回复了<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@load</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>loadReply<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>3）获取数据：</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line"> import { getCommentsByArticle, likeArticle, collectArticle, getReplysByComment } from '@/api/article'
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token keyword">async</span> <span class="token function">loadReply</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getReplysByComment</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>currComments<span class="token punctuation">.</span>com_id<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>offset<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token operator">...</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>results<span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>end_id <span class="token operator">===</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>last_id<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>finished <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>offset <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>last_id
      <span class="token punctuation">}</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>reply<span class="token punctuation">.</span>loading <span class="token operator">=</span> <span class="token boolean">false</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><p>4）进行渲染：</p> <div class="language-vue extra-class"><pre class="language-vue"><code>          <span class="token comment">&lt;!-- 列表 --&gt;</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item van-hairline--bottom<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item in reply.list<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.com_id<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">width</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">height</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>10vw<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.aut_photo<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.aut_name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
                <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>zan<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.like_count}} <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>like2<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cont<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.content}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>time<span class="token punctuation">&quot;</span></span> <span class="token style-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token style language-css"><span class="token property">margin-left</span><span class="token punctuation">:</span>0</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>{{item.pubdate|relativeTime}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_09-填写文章评论"><a href="#_09-填写文章评论" class="header-anchor">#</a> 09-填写文章评论</h3> <blockquote><p>目的：发表对文章评论</p></blockquote> <p>大致步骤：</p> <ul><li>准备填写文字的弹出框</li> <li>定义API接口函数，点击发表提交评论</li></ul> <p>落地代码：</p> <ul><li>准备填写文字的弹出框   <code>src/views/article/components/article-comment.vue</code></li></ul> <p>1）弹出框</p> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 评论&amp;回复 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-popup</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showInput<span class="token punctuation">&quot;</span></span> <span class="token attr-name">position</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-nav-bar</span> <span class="token attr-name">left-arrow</span> <span class="token attr-name">@click-left</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showInput=false<span class="token punctuation">&quot;</span></span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>评论文章<span class="token punctuation">&quot;</span></span> <span class="token attr-name">right-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>发表<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span>
        <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">rows</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>3<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">autosize</span>
        <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>textarea<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">maxlength</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>100<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请输入评论<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">show-word-limit</span>
      <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-popup</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">::v-deep .van-nav-bar__text</span> <span class="token punctuation">{</span>
  <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">@geek-color</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">::v-deep .van-field__control</span> <span class="token punctuation">{</span>
  <span class="token property">background</span><span class="token punctuation">:</span> <span class="token variable">@geek-gray-color</span><span class="token punctuation">;</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 5px 10px<span class="token punctuation">;</span>
  <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span>
  <span class="token property">border-radius</span><span class="token punctuation">:</span> 4px<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>2）数据</p> <div class="language-js extra-class"><pre class="language-js"><code>      <span class="token comment">// 显示输入弹窗</span>
      showInput<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
      <span class="token comment">// 输入框值</span>
      text<span class="token operator">:</span> <span class="token string">''</span>
</code></pre></div><p>3）打开对话框</p> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 底部工具 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>footer van-hairline--top<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showInput=true<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>定义API接口函数，点击发表提交评论，更新数据，关闭对话框</li></ul> <p><code>src/api/article.js</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 对文章进行评论，对评论进行回复
 * @param {*} target - 评论：文章ID，回复：评论ID
 * @param {*} content - 内容
 * @param {*} articleId - 回复：文章ID
 * @returns
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">commentOrReply</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">target<span class="token punctuation">,</span> content<span class="token punctuation">,</span> articleId <span class="token operator">=</span> <span class="token keyword">null</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/comments'</span><span class="token punctuation">,</span>
    method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span>
    data<span class="token operator">:</span> <span class="token punctuation">{</span> target<span class="token punctuation">,</span> content<span class="token punctuation">,</span> art_id<span class="token operator">:</span> articleId <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p><code>src/views/article/components/article-comment.vue</code></p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-nav-bar
</span><span class="token prefix unchanged"> </span><span class="token line">       left-arrow
</span><span class="token prefix unchanged"> </span><span class="token line">       @click-left=&quot;showInput=false&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       title=&quot;评论文章&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       right-text=&quot;发表&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        @click-right=&quot;submit()&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     /&gt;
</span></span></code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code>import {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> getCommentsByArticle,
</span><span class="token prefix unchanged"> </span><span class="token line"> likeArticle,
</span><span class="token prefix unchanged"> </span><span class="token line"> collectArticle,
</span><span class="token prefix unchanged"> </span><span class="token line"> getReplysByComment,
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  commentOrReply
</span></span>} from '@/api/articles'
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token keyword">async</span> <span class="token function">submit</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 1. 提交文章评论</span>
        <span class="token comment">// 1.1. 校验是否输入内容</span>
        <span class="token comment">// 1.2. 调用接口</span>
        <span class="token comment">// 1.3. 失败提示</span>
        <span class="token comment">// 1.4. 更新评论列表+更新评论数量+关闭对话框+清除输入内容+成功提示</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>text<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$toast</span><span class="token punctuation">(</span><span class="token string">'请输入评论'</span><span class="token punctuation">)</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">commentOrReply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>art_id<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>text<span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'评论失败'</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>comments<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>new_obj<span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>article<span class="token punctuation">.</span>comm_count<span class="token operator">++</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>showInput <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>text <span class="token operator">=</span> <span class="token string">''</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'评论成功'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_10-填写评论回复"><a href="#_10-填写评论回复" class="header-anchor">#</a> 10-填写评论回复</h3> <blockquote><p>目的：发表对评论的回复</p></blockquote> <p>大致步骤：</p> <ul><li>关闭回复列表弹出框清除评论对象，（判断此操作是回复还是评论，根据对象是否有数据）</li> <li>点击发表按钮，在 <code>submit</code> 函数，合并提交回复功能</li></ul> <p>落地代码：</p> <ul><li>关闭回复列表弹出框清除评论对象，动态渲染输入框 placeholder 和 弹出框标题</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 回复弹层 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-popup</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply.open<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@closed</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>currComments={}<span class="token punctuation">&quot;</span></span> <span class="token attr-name">position</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>right<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;!-- 评论&amp;回复 --&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;van-popup v-model=&quot;showInput&quot; position=&quot;bottom&quot;&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-nav-bar
</span><span class="token prefix unchanged"> </span><span class="token line">       left-arrow
</span><span class="token prefix unchanged"> </span><span class="token line">       @click-left=&quot;showInput=false&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        :title=&quot;currComments.com_id?'回复评论':'评论文章'&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       right-text=&quot;发表&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       @click-right=&quot;submit()&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">     /&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-field
</span><span class="token prefix unchanged"> </span><span class="token line">       v-model=&quot;text&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       rows=&quot;3&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       autosize
</span><span class="token prefix unchanged"> </span><span class="token line">       type=&quot;textarea&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       maxlength=&quot;100&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        :placeholder=&quot;currComments.com_id?`@${currComments.aut_name}`:'请输入评论'&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       show-word-limit
</span><span class="token prefix unchanged"> </span><span class="token line">     /&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-popup&gt;
</span></span></code></pre></div><ul><li>合并提交回复功能</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   async submit () {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      if (!this.currComments.com_id) {
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       // 1. 提交文章评论
</span><span class="token prefix unchanged"> </span><span class="token line">       // 1.1. 校验是否输入内容
</span><span class="token prefix unchanged"> </span><span class="token line">       // 1.2. 调用接口
</span><span class="token prefix unchanged"> </span><span class="token line">       // 1.3. 失败提示
</span><span class="token prefix unchanged"> </span><span class="token line">       // 1.4. 更新评论列表+更新评论数量+关闭对话框+清除输入内容+成功提示
</span><span class="token prefix unchanged"> </span><span class="token line">       if (!this.text) return this.$toast('请输入评论')
</span><span class="token prefix unchanged"> </span><span class="token line">       const [err, res] = await commentOrReply(this.article.art_id, this.text)
</span><span class="token prefix unchanged"> </span><span class="token line">       if (err) return this.$toast.fail('评论失败')
</span><span class="token prefix unchanged"> </span><span class="token line">       this.comments.unshift(res.data.data.new_obj)
</span><span class="token prefix unchanged"> </span><span class="token line">       this.article.comm_count++
</span><span class="token prefix unchanged"> </span><span class="token line">       this.showInput = false
</span><span class="token prefix unchanged"> </span><span class="token line">       this.text = ''
</span><span class="token prefix unchanged"> </span><span class="token line">       this.$toast.success('评论成功')
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      } else {
</span><span class="token prefix inserted">+</span><span class="token line">        // 2. 提交评论回复
</span><span class="token prefix inserted">+</span><span class="token line">        // 2.1. 校验是否输入内容
</span><span class="token prefix inserted">+</span><span class="token line">        // 2.2. 调用接口
</span><span class="token prefix inserted">+</span><span class="token line">        // 2.3. 失败提示
</span><span class="token prefix inserted">+</span><span class="token line">        // 2.4. 更新回复列表+更新评论数量+更新回复数量+关闭对话框+清除输入内容+成功提示
</span><span class="token prefix inserted">+</span><span class="token line">        if (!this.text) return this.$toast('请输入回复')
</span><span class="token prefix inserted">+</span><span class="token line">        const [err, res] = await commentOrReply(this.currComments.com_id, this.text, this.article.art_id)
</span><span class="token prefix inserted">+</span><span class="token line">        if (err) return this.$toast.fail('回复失败')
</span><span class="token prefix inserted">+</span><span class="token line">        this.reply.list.unshift(res.data.data.new_obj)
</span><span class="token prefix inserted">+</span><span class="token line">        this.article.comm_count++
</span><span class="token prefix inserted">+</span><span class="token line">        this.currComments.reply_count++
</span><span class="token prefix inserted">+</span><span class="token line">        this.showInput = false
</span><span class="token prefix inserted">+</span><span class="token line">        this.text = ''
</span><span class="token prefix inserted">+</span><span class="token line">        this.$toast.success('回复成功')
</span><span class="token prefix inserted">+</span><span class="token line">      }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   },
</span></span></code></pre></div><h2 id="第八章-个人中心"><a href="#第八章-个人中心" class="header-anchor">#</a> 第八章：个人中心</h2> <h3 id="_01-个人中心-基础布局"><a href="#_01-个人中心-基础布局" class="header-anchor">#</a> 01-个人中心-基础布局</h3> <blockquote><p>目的：完成个人中心首页基础布局</p></blockquote> <img src="/document/assets/img/1627210383233.bfdf9a6c.png" alt="1627210383233" style="zoom:67%;"> <p>大致步骤：</p> <ul><li>根据笔记完成布局</li> <li>了解布局结构样式</li></ul> <p>落地代码： <code>src/user/index.vue</code></p> <ul><li>根据笔记完成布局</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>user-page<span class="token punctuation">'</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user-profile<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">fit</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cover<span class="token punctuation">&quot;</span></span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://img01.yzcdn.cn/vant/cat.jpeg<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>清风徐来<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>router-link</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/user/profile<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>个人信息<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>arrow<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>router-link</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-row</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>动态<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>关注<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>粉丝<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>0<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>被赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-row</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-row</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user-links<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>message<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>消息通知
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>mycollect<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>我的收藏
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>history<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>阅读历史
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>myworks<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>我的作品
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-row</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>more<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>更多服务<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-row</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>feedback2<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>用户反馈
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span>  <span class="token attr-name">@click.native</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$router.push(<span class="token punctuation">'</span>/user/chat<span class="token punctuation">'</span>)<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>xiaozhi<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>小智同学
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-row</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserPage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">scoped</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>less<span class="token punctuation">'</span></span><span class="token punctuation">&gt;</span></span><span class="token style"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">.user-page</span> <span class="token punctuation">{</span>
  <span class="token property">background</span><span class="token punctuation">:</span> #fafafa<span class="token punctuation">;</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token selector">.more</span> <span class="token punctuation">{</span>
  <span class="token property">margin</span><span class="token punctuation">:</span> 0 15px<span class="token punctuation">;</span>
  <span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
  <span class="token property">border-radius</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 120px<span class="token punctuation">;</span>
  <span class="token selector">p</span> <span class="token punctuation">{</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 10px 15px<span class="token punctuation">;</span>
    <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-row</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 15px 0<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token selector">.geek-icon</span> <span class="token punctuation">{</span>
      <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 22px<span class="token punctuation">;</span>
      <span class="token property">padding-bottom</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token selector">.user</span> <span class="token punctuation">{</span>
  <span class="token selector">&amp;-profile</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 15px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 240px<span class="token punctuation">;</span>
    <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token function">linear-gradient</span><span class="token punctuation">(</span>318deg<span class="token punctuation">,</span>#B2B5DB 0%<span class="token punctuation">,</span>#565482 70%<span class="token punctuation">,</span>#494675 100%<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
    <span class="token property">border-bottom-left-radius</span><span class="token punctuation">:</span> 400px 60px<span class="token punctuation">;</span>
    <span class="token property">border-bottom-right-radius</span><span class="token punctuation">:</span> 400px 60px<span class="token punctuation">;</span>
    <span class="token property">margin-bottom</span><span class="token punctuation">:</span> 48px<span class="token punctuation">;</span>
    <span class="token selector">.info</span> <span class="token punctuation">{</span>
      <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 40px 0<span class="token punctuation">;</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 130px<span class="token punctuation">;</span>
      <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token selector">.van-image</span> <span class="token punctuation">{</span>
        <span class="token property">width</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
        <span class="token property">height</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
        <span class="token property">border</span><span class="token punctuation">:</span> 3px solid #7674a2<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">.name</span> <span class="token punctuation">{</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
        <span class="token property">font-weight</span><span class="token punctuation">:</span> normal<span class="token punctuation">;</span>
        <span class="token property">margin-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
        <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">.btn</span> <span class="token punctuation">{</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
        <span class="token selector">.van-icon</span> <span class="token punctuation">{</span>
          <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
          <span class="token property">top</span><span class="token punctuation">:</span> 1px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token selector">p</span> <span class="token punctuation">{</span>
      <span class="token property">margin</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
      <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
      <span class="token property">height</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">&amp;-links</span> <span class="token punctuation">{</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 20px 0<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 12px<span class="token punctuation">;</span>
    <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
    <span class="token property">background-color</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #333<span class="token punctuation">;</span>
    <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
    <span class="token property">top</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
    <span class="token selector">.geek-icon</span> <span class="token punctuation">{</span>
      <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
      <span class="token property">font-size</span><span class="token punctuation">:</span> 22px<span class="token punctuation">;</span>
      <span class="token property">padding-bottom</span><span class="token punctuation">:</span> 5px<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>了解布局结构样式</li></ul> <div class="language-tex extra-class"><pre class="language-tex"><code>1. info 作者信息
2. van-row 统计信息
3. van-row.user-links 用户信息相关链接
4. .more 更多服务
</code></pre></div><h3 id="_02-个人中心-渲染页面"><a href="#_02-个人中心-渲染页面" class="header-anchor">#</a> 02-个人中心-渲染页面</h3> <blockquote><p>目的：获取当前用户信息渲染页面</p></blockquote> <p>大致步骤：</p> <ul><li>定义API函数</li> <li>组件初始获取数据</li> <li>进行渲染</li></ul> <p>落地代码：</p> <ul><li>定义API函数 <code>src/api/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取当前用户的信息（资料和统计）
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getUserInfo</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'/v1_0/user'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>个人中心组件初始化获取数据 <code>src/views/user/index.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getUserInfo <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserPage'</span><span class="token punctuation">,</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      user<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getUserInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// 获取个人信息</span>
    <span class="token keyword">async</span> <span class="token function">getUserInfo</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getUserInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>user <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>进行渲染</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>info<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">round</span> <span class="token attr-name">fit</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cover<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.photo<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h3</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{user.name}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h3</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>router-link</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>btn<span class="token punctuation">&quot;</span></span> <span class="token attr-name">to</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/user/profile<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>个人信息<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>arrow<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>router-link</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-row</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>{{user.art_count}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>动态<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>{{user.follow_count}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>关注<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>{{user.fans_count}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>粉丝<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-col</span> <span class="token attr-name">span</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>6<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>{{user.like_count}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>被赞<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-col</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-row</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_03-编辑资料-页面布局"><a href="#_03-编辑资料-页面布局" class="header-anchor">#</a> 03-编辑资料-页面布局</h3> <blockquote><p>目的：完成编辑资料页面布局，了解结构</p></blockquote> <img src="/document/assets/img/1627219161998.c839b80c.png" alt="1627219161998" style="zoom:67%;"> <p>大致步骤：</p> <ul><li>配置路由组件</li> <li>根据笔记完成布局</li> <li>了解布局结构样式</li></ul> <p>落地代码：</p> <ul><li>组件 <code>src/views/user/profile/index.vue</code></li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">'</span>user-profile-page<span class="token punctuation">'</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-nav-bar</span> <span class="token attr-name">left-arrow</span> <span class="token attr-name">@click-left</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$router.back()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>个人信息<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-nav-bar</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell-group</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>头像<span class="token punctuation">&quot;</span></span> <span class="token attr-name">center</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span>
          <span class="token attr-name">slot</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>default<span class="token punctuation">&quot;</span></span>
          <span class="token attr-name">fit</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cover<span class="token punctuation">&quot;</span></span>
          <span class="token attr-name">round</span>
          <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>https://img01.yzcdn.cn/vant/cat.jpeg<span class="token punctuation">&quot;</span></span>
        <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-cell</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>昵称<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>清风徐来<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-cell-group</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell-group</span> <span class="token style-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token style language-css"><span class="token property">margin-top</span><span class="token punctuation">:</span>12px</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>性别<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>男<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>生日<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>2020-10-10<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-cell-group</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>logout<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span>退出登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserProfilePage'</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.user-profile-page</span> <span class="token punctuation">{</span>
  <span class="token property">background</span><span class="token punctuation">:</span> #f8f8f8<span class="token selector">;
  .van-image</span> <span class="token punctuation">{</span>
    <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
    <span class="token property">float</span><span class="token punctuation">:</span> right<span class="token punctuation">;</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 30px<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 30px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">.van-cell__title</span> <span class="token punctuation">{</span>
    <span class="token property">width</span><span class="token punctuation">:</span> 50px<span class="token punctuation">;</span>
    <span class="token property">flex</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token selector">.logout</span> <span class="token punctuation">{</span>
  <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
  <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
  <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">bottom</span><span class="token punctuation">:</span> 30px<span class="token punctuation">;</span>
  <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">color</span><span class="token punctuation">:</span> <span class="token atrule"><span class="token rule">@geek-color</span><span class="token punctuation">;</span></span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>路由 <code>src/router/index.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">UserProfile</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'@/views/user/profile'</span><span class="token punctuation">)</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">{</span> path<span class="token operator">:</span> <span class="token string">'/user/profile'</span><span class="token punctuation">,</span> component<span class="token operator">:</span> UserProfile <span class="token punctuation">}</span>
</code></pre></div><h3 id="_04-编辑资料-回显数据"><a href="#_04-编辑资料-回显数据" class="header-anchor">#</a> 04-编辑资料-回显数据</h3> <blockquote><p>目的，获取个人资料回显页面</p></blockquote> <p>大致步骤：</p> <ul><li>定义API函数</li> <li>组件初始获取数据</li> <li>进行渲染</li></ul> <p>落地代码：</p> <ul><li>定义API函数 <code>src/api/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 获取当前用户的资料
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getUserProfile</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span> url<span class="token operator">:</span> <span class="token string">'/v1_0/user/profile'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>组件初始获取数据 <code>src/views/user/profile.vue</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getUserProfile <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserProfilePage'</span><span class="token punctuation">,</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      user<span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getUserProfile</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">async</span> <span class="token function">getUserProfile</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getUserProfile</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>user <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>进行渲染 <code>src/views/user/profile.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;van-cell-group&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;van-cell is-link title=&quot;头像&quot; center&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       &lt;van-image
</span><span class="token prefix unchanged"> </span><span class="token line">         slot=&quot;default&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         fit=&quot;cover&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">         round
</span><span class="token prefix unchanged"> </span><span class="token line">         :src=&quot;user.photo&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       /&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">     &lt;/van-cell&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;van-cell is-link title=&quot;昵称&quot; :value=&quot;user.name||'未填写'&quot; /&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-cell-group&gt;
</span><span class="token prefix unchanged"> </span><span class="token line">   &lt;van-cell-group style=&quot;margin-top:12px&quot;&gt;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      &lt;van-cell is-link title=&quot;性别&quot; :value=&quot;user.gender===0?'男':'女'&quot; /&gt;
</span><span class="token prefix inserted">+</span><span class="token line">      &lt;van-cell is-link title=&quot;生日&quot; :value=&quot;user.birthday||'未填写'&quot; /&gt;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   &lt;/van-cell-group&gt;
</span></span></code></pre></div><h3 id="_05-编辑资料-退出登录"><a href="#_05-编辑资料-退出登录" class="header-anchor">#</a> 05-编辑资料-退出登录</h3> <blockquote><p>目的：退出登录</p></blockquote> <p>大致步骤：</p> <ul><li>绑定事件</li> <li>处理函数，弹出确认框</li> <li>确认，删除token，跳转首页，提示退出</li></ul> <p>落地代码:</p> <ul><li>绑定事件</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>logout<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>退出登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>弹出确认框</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token function">logout</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$dialog<span class="token punctuation">.</span><span class="token function">confirm</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        title<span class="token operator">:</span> <span class="token string">'温馨提示'</span><span class="token punctuation">,</span>
        message<span class="token operator">:</span> <span class="token string">'您确认退出极客园吗？'</span><span class="token punctuation">,</span>
        theme<span class="token operator">:</span> <span class="token string">'round-button'</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$store<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">'user/setToken'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$router<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'退出登录'</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
</code></pre></div><h3 id="_06-编辑资料-修改头像"><a href="#_06-编辑资料-修改头像" class="header-anchor">#</a> 06-编辑资料-修改头像</h3> <blockquote><p>目的：点击头像，弹出选项，点击本地上传，完成修改头像</p></blockquote> <p>大致步骤：</p> <ul><li>使用vant的动作面板组件，显示 本地上传  拍照 取消 选项</li> <li>调用本地上传，触发 input type=&quot;file&quot;  的点击事件</li> <li>监听选择文件完成，调用封装号的API上传函数</li> <li>失败提示，成功（更新数据+提示）</li></ul> <p>大致步骤：</p> <ul><li>api函数 <code>src/api/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 修改头像
 * @param {Object} formData -  {photo:'文件数据'}
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">updateUserPhoto</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">formData</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/user/photo'</span><span class="token punctuation">,</span>
    method<span class="token operator">:</span> <span class="token string">'patch'</span><span class="token punctuation">,</span>
    data<span class="token operator">:</span> formData
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>点击头像，显示动作面板</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     user: {},
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      // 修改头像相关数据
</span><span class="token prefix inserted">+</span><span class="token line">      showPhoto: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>头像<span class="token punctuation">&quot;</span></span> <span class="token attr-name">center</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showPhoto=true<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 修改头像-弹出层 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-action-sheet</span>
      <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showPhoto<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">:actions</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>[{ name: <span class="token punctuation">'</span>拍照<span class="token punctuation">'</span>, value: 0 },{ name: <span class="token punctuation">'</span>本地选择<span class="token punctuation">'</span>, value: 1 }]<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">@select</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>onPhotoSelect<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">cancel-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>取消<span class="token punctuation">&quot;</span></span>
    <span class="token punctuation">/&gt;</span></span>
</code></pre></div><ul><li>点击本地上传，调用file输入框</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">@change</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>updatePhoto<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>file<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>file<span class="token punctuation">&quot;</span></span> <span class="token style-attr"><span class="token attr-name">style</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span><span class="token style language-css"><span class="token property">display</span><span class="token punctuation">:</span>none</span><span class="token punctuation">&quot;</span></span></span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 选择修改头像-动作面板选项</span>
    <span class="token function">onPhotoSelect</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>item<span class="token punctuation">.</span>value <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 本地选择</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>file<span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>showPhoto <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>选择文件后完成上传</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 修改头像</span>
    <span class="token keyword">async</span> <span class="token function">updatePhoto</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 选择图片后的文件信息对象</span>
      <span class="token keyword">const</span> file <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$refs<span class="token punctuation">.</span>file<span class="token punctuation">.</span>files<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
      <span class="token comment">// 打开资源管理器，不选选图片，点击取消 file 是空的</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>file<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// 上传图片</span>
        <span class="token comment">// 1. 包装一个formData对象，字段名字photo指向的是选择的图片</span>
        <span class="token keyword">const</span> formData <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FormData</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        formData<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token string">'photo'</span><span class="token punctuation">,</span> file<span class="token punctuation">)</span>
        <span class="token comment">// 2. 调用API接口</span>
        <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">updateUserPhoto</span><span class="token punctuation">(</span>formData<span class="token punctuation">)</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'修改失败'</span><span class="token punctuation">)</span>
        <span class="token comment">// 3. 显示上传成功的头像，成功提示</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>user<span class="token punctuation">.</span>photo <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>photo
        <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'修改成功'</span><span class="token punctuation">)</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_07-编辑资料-修改昵称"><a href="#_07-编辑资料-修改昵称" class="header-anchor">#</a> 07-编辑资料-修改昵称</h3> <blockquote><p>目的：调用弹出框修改昵称</p></blockquote> <p>落地代码：</p> <ul><li>准备弹出框</li> <li>定义API函数</li> <li>完成保存</li></ul> <p>落地代码：</p> <ul><li>准备弹出框 <code>src/views/user/profile/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     user: {},
</span><span class="token prefix unchanged"> </span><span class="token line">     // 修改头像相关数据
</span><span class="token prefix unchanged"> </span><span class="token line">     showPhoto: false,
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      // 修改用户名称
</span><span class="token prefix inserted">+</span><span class="token line">      showName: false,
</span><span class="token prefix inserted">+</span><span class="token line">      name: ''
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>昵称<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>openNamePopup()<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.name||<span class="token punctuation">'</span>未填写<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 打开修改名称弹出框</span>
    <span class="token function">openNamePopup</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>showName <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>user<span class="token punctuation">.</span>name
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 修改昵称 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-popup</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>my-popup<span class="token punctuation">&quot;</span></span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">position</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>right<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-nav-bar</span>
        <span class="token attr-name">left-arrow</span>
        <span class="token attr-name">@click-left</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showName=false<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">right-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>保存<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>修改昵称<span class="token punctuation">&quot;</span></span>
      <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>name<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-popup</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-less extra-class"><pre class="language-less"><code><span class="token selector">.my-popup</span> <span class="token punctuation">{</span>
  <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token selector">/deep/ .van-nav-bar__text</span> <span class="token punctuation">{</span>
    <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">@geek-color</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token selector">/deep/ .van-field__control</span> <span class="token punctuation">{</span>
    <span class="token property">background</span><span class="token punctuation">:</span> <span class="token variable">@geek-gray-color</span><span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> 4px<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>API函数 <code>src/api/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 修改用户
 * @param {Object} user - 用户对象
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">updateUser</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> <span class="token string">'/v1_0/user/profile'</span><span class="token punctuation">,</span>
    method<span class="token operator">:</span> <span class="token string">'patch'</span><span class="token punctuation">,</span>
    data<span class="token operator">:</span> user
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><ul><li>完成保存  <code>src/views/user/profile/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     &lt;van-nav-bar
</span><span class="token prefix unchanged"> </span><span class="token line">       left-arrow
</span><span class="token prefix unchanged"> </span><span class="token line">       @click-left=&quot;showName=false&quot;
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        @click-right=&quot;saveName()&quot;
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       right-text=&quot;保存&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">       title=&quot;修改昵称&quot;
</span><span class="token prefix unchanged"> </span><span class="token line">     /&gt;
</span></span></code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 保存昵称</span>
    <span class="token keyword">async</span> <span class="token function">saveName</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$toast</span><span class="token punctuation">(</span><span class="token string">'请输入昵称'</span><span class="token punctuation">)</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">updateUserProfile</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'更新失败'</span><span class="token punctuation">)</span>
      <span class="token comment">// 更新单元格中的昵称</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>user<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name
      <span class="token keyword">this</span><span class="token punctuation">.</span>showName <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'更新成功'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_08-编辑资料-修改性别"><a href="#_08-编辑资料-修改性别" class="header-anchor">#</a> 08-编辑资料-修改性别</h3> <blockquote><p>目的：完成修改性别</p></blockquote> <p>大致步骤：</p> <ul><li>准备动作面板</li> <li>选择后保存</li></ul> <p>大致步骤：</p> <ul><li>准备动作面板</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     user: {},
</span><span class="token prefix unchanged"> </span><span class="token line">     // 修改头像相关数据
</span><span class="token prefix unchanged"> </span><span class="token line">     showPhoto: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 修改用户名称
</span><span class="token prefix unchanged"> </span><span class="token line">     showName: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     name: '',
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      // 修改用户性别
</span><span class="token prefix inserted">+</span><span class="token line">      showGender: false
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 修改性别 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-action-sheet</span>
      <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showGender<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">:actions</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>[{ name: <span class="token punctuation">'</span>男<span class="token punctuation">'</span>, value: 0 }, { name: <span class="token punctuation">'</span>女<span class="token punctuation">'</span>, value: 1 }]<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">@select</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>saveGender<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">cancel-text</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>取消<span class="token punctuation">&quot;</span></span>
    <span class="token punctuation">/&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>性别<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showGender=true<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.gender===0?<span class="token punctuation">'</span>男<span class="token punctuation">'</span>:<span class="token punctuation">'</span>女<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><ul><li>选择后保存</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 修改用户性别</span>
    <span class="token keyword">async</span> <span class="token function">saveGender</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">updateUser</span><span class="token punctuation">(</span><span class="token punctuation">{</span> gender<span class="token operator">:</span> item<span class="token punctuation">.</span>value <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'更新失败'</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>user<span class="token punctuation">.</span>gender <span class="token operator">=</span> item<span class="token punctuation">.</span>value
      <span class="token keyword">this</span><span class="token punctuation">.</span>showGender <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'更新成功'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_09-编辑资料-修改生日"><a href="#_09-编辑资料-修改生日" class="header-anchor">#</a> 09-编辑资料-修改生日</h3> <blockquote><p>目的：完成修改生日</p></blockquote> <p>大致步骤：</p> <ul><li>准备日期选择器组件</li> <li>确认时间后保存生日</li></ul> <p>落地代码：</p> <ul><li>准备日期选择器组件</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     user: {},
</span><span class="token prefix unchanged"> </span><span class="token line">     // 修改头像相关数据
</span><span class="token prefix unchanged"> </span><span class="token line">     showPhoto: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     // 修改用户名称
</span><span class="token prefix unchanged"> </span><span class="token line">     showName: false,
</span><span class="token prefix unchanged"> </span><span class="token line">     name: '',
</span><span class="token prefix unchanged"> </span><span class="token line">     // 修改用户性别
</span><span class="token prefix unchanged"> </span><span class="token line">     showGender: false,
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      // 修改生日
</span><span class="token prefix inserted">+</span><span class="token line">      showBirthday: false,
</span><span class="token prefix inserted">+</span><span class="token line">      birthday: new Date(),
</span><span class="token prefix inserted">+</span><span class="token line">      minDate: new Date('1960-01-01'),
</span><span class="token prefix inserted">+</span><span class="token line">      maxDate: new Date()
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 修改生日 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-popup</span> <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showBirthday<span class="token punctuation">&quot;</span></span> <span class="token attr-name">position</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>bottom<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-datetime-picker</span>
        <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>birthday<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>date<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>选择年月日<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">:min-date</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>minDate<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">:max-date</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>maxDate<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">@cancel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>showBirthday=false<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>saveBirthday<span class="token punctuation">&quot;</span></span>
      <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-popup</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-cell</span> <span class="token attr-name">is-link</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>生日<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>openBirthdayPopup<span class="token punctuation">&quot;</span></span> <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user.birthday||<span class="token punctuation">'</span>未填写<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 打开日期选择器</span>
    <span class="token function">openBirthdayPopup</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>showBirthday <span class="token operator">=</span> <span class="token boolean">true</span>
      <span class="token comment">// 给日期控件赋值，当前用户的生日</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>birthday <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>user<span class="token punctuation">.</span>birthday<span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><ul><li>确认时间后保存生日</li></ul> <div class="language-js extra-class"><pre class="language-js"><code>    <span class="token comment">// 修改用户生日</span>
    <span class="token keyword">async</span> <span class="token function">saveBirthday</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 转换格式</span>
      <span class="token keyword">const</span> date <span class="token operator">=</span> <span class="token function">dayjs</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>birthday<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'YYYY-MM-DD'</span><span class="token punctuation">)</span>
      <span class="token keyword">const</span> <span class="token punctuation">[</span>err<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">updateUser</span><span class="token punctuation">(</span><span class="token punctuation">{</span> birthday<span class="token operator">:</span> date <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">fail</span><span class="token punctuation">(</span><span class="token string">'更新失败'</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>user<span class="token punctuation">.</span>birthday <span class="token operator">=</span> date
      <span class="token keyword">this</span><span class="token punctuation">.</span>showBirthday <span class="token operator">=</span> <span class="token boolean">false</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>$toast<span class="token punctuation">.</span><span class="token function">success</span><span class="token punctuation">(</span><span class="token string">'更新成功'</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><h3 id="_10-小智同学-基础布局"><a href="#_10-小智同学-基础布局" class="header-anchor">#</a> 10-小智同学-基础布局</h3> <blockquote><p>目的：搭建小智同学的基础布局</p></blockquote> <img src="/document/assets/img/1627227400490.513a51ad.png" alt="1627227400490" style="zoom:67%;"> <p>大致步骤：</p> <ul><li>完成布局</li> <li>了解结构</li> <li>准备用户头像数据</li></ul> <p>落地代码：<code>src/views/user/chat.vue</code></p> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>user-chat-page<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-nav-bar</span>
      <span class="token attr-name">fixed</span>
      <span class="token attr-name">left-arrow</span>
      <span class="token attr-name">@click-left</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>$router.back()<span class="token punctuation">&quot;</span></span>
      <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>小智同学<span class="token punctuation">&quot;</span></span>
    <span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-nav-bar</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 聊天列表 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-list<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>list<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-item left<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>xiaozhi<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-pao<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>我是小智同学，需要什么帮助吗？<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-item right<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-pao<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>报名前端<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">fit</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cover<span class="token punctuation">&quot;</span></span> <span class="token attr-name">round</span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>myAvatar<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- 输入框 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>reply-container van-hairline--top<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-field</span>
        <span class="token attr-name">v-model.trim</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>value<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">left-icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>edit<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">placeholder</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>请描述您的问题<span class="token punctuation">&quot;</span></span>
      <span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>van-field</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>send<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>发送<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> <span class="token punctuation">{</span> getUserProfile <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserChatPage'</span><span class="token punctuation">,</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      myAvatar<span class="token operator">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
      <span class="token comment">// list: [</span>
      <span class="token comment">//   { name: 'xz', msg: '我是小智同学，需要什么帮助吗？' },</span>
      <span class="token comment">//   { name: 'my', msg: '报名前端' }</span>
      <span class="token comment">// ],</span>
      value<span class="token operator">:</span> <span class="token string">''</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getUserProfile</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>myAvatar <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>photo
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>less<span class="token punctuation">&quot;</span></span> <span class="token attr-name">scoped</span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
<span class="token selector">.user-chat-page</span> <span class="token punctuation">{</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
  <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">top</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span>
  <span class="token property">background</span><span class="token punctuation">:</span>#fff<span class="token punctuation">;</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 46px 0 50px 0<span class="token selector">;
  .chat-list</span> <span class="token punctuation">{</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
    <span class="token property">overflow-y</span><span class="token punctuation">:</span> scroll<span class="token selector">;
    .chat-item</span><span class="token punctuation">{</span>
      <span class="token property">padding</span><span class="token punctuation">:</span> 10px<span class="token selector">;
      .van-image</span><span class="token punctuation">{</span>
        <span class="token property">vertical-align</span><span class="token punctuation">:</span> middle<span class="token punctuation">;</span>
        <span class="token property">width</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
        <span class="token property">height</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">.geek-icon</span> <span class="token punctuation">{</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token selector">.chat-pao</span><span class="token punctuation">{</span>
        <span class="token property">vertical-align</span><span class="token punctuation">:</span> top<span class="token punctuation">;</span>
        <span class="token property">display</span><span class="token punctuation">:</span> inline-block<span class="token punctuation">;</span>
        <span class="token property">min-width</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
        <span class="token property">max-width</span><span class="token punctuation">:</span> 70%<span class="token punctuation">;</span>
        <span class="token property">min-height</span><span class="token punctuation">:</span> 40px<span class="token punctuation">;</span>
        <span class="token property">line-height</span><span class="token punctuation">:</span> 20px<span class="token punctuation">;</span>
        <span class="token property">border-radius</span><span class="token punctuation">:</span> 4px<span class="token punctuation">;</span>
        <span class="token property">position</span><span class="token punctuation">:</span> relative<span class="token punctuation">;</span>
        <span class="token property">padding</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
        <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token atrule"><span class="token rule">@geek-gray-color</span><span class="token punctuation">;</span></span>
        <span class="token property">word-break</span><span class="token punctuation">:</span> break-all<span class="token punctuation">;</span>
        <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
        <span class="token property">color</span><span class="token punctuation">:</span> #333<span class="token selector">;
        &amp;::before</span><span class="token punctuation">{</span>
          <span class="token property">content</span><span class="token punctuation">:</span> <span class="token string">&quot;&quot;</span><span class="token punctuation">;</span>
          <span class="token property">width</span><span class="token punctuation">:</span> 6px<span class="token punctuation">;</span>
          <span class="token property">height</span><span class="token punctuation">:</span> 6px<span class="token punctuation">;</span>
          <span class="token property">position</span><span class="token punctuation">:</span> absolute<span class="token punctuation">;</span>
          <span class="token property">top</span><span class="token punctuation">:</span> 15px<span class="token punctuation">;</span>
          <span class="token property">background</span><span class="token punctuation">:</span>  <span class="token atrule"><span class="token rule">@geek-gray-color</span><span class="token punctuation">;</span></span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token selector">.chat-item.right</span><span class="token punctuation">{</span>
  <span class="token property">text-align</span><span class="token punctuation">:</span> right<span class="token selector">;
  .chat-pao</span><span class="token punctuation">{</span>
    <span class="token property">margin-left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
    <span class="token property">margin-right</span><span class="token punctuation">:</span> 10px<span class="token selector">;
    &amp;::before</span><span class="token punctuation">{</span>
      <span class="token property">right</span><span class="token punctuation">:</span> -3px<span class="token punctuation">;</span>
      <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>45deg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token selector">.chat-item.left</span><span class="token punctuation">{</span>
  <span class="token property">text-align</span><span class="token punctuation">:</span> left<span class="token selector">;
  .chat-pao</span><span class="token punctuation">{</span>
    <span class="token property">margin-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
    <span class="token property">margin-right</span><span class="token punctuation">:</span> 0<span class="token selector">;
    &amp;::before</span><span class="token punctuation">{</span>
      <span class="token property">left</span><span class="token punctuation">:</span> -3px<span class="token punctuation">;</span>
      <span class="token property">transform</span><span class="token punctuation">:</span> <span class="token function">rotate</span><span class="token punctuation">(</span>-135deg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token selector">.reply-container</span> <span class="token punctuation">{</span>
  <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span>
  <span class="token property">left</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">bottom</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span>
  <span class="token property">height</span><span class="token punctuation">:</span> 49px<span class="token punctuation">;</span>
  <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
  <span class="token property">background</span><span class="token punctuation">:</span> #fff<span class="token punctuation">;</span>
  <span class="token property">z-index</span><span class="token punctuation">:</span> 9999<span class="token punctuation">;</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">align-items</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
  <span class="token property">padding</span><span class="token punctuation">:</span> 0 10px<span class="token selector">;
  &gt; .van-field</span> <span class="token punctuation">{</span>
    <span class="token property">flex</span><span class="token punctuation">:</span> 1<span class="token punctuation">;</span>
    <span class="token property">background</span><span class="token punctuation">:</span> #F7F8FA<span class="token punctuation">;</span>
    <span class="token property">height</span><span class="token punctuation">:</span> 32px<span class="token punctuation">;</span>
    <span class="token property">border-radius</span><span class="token punctuation">:</span> 16px<span class="token punctuation">;</span>
    <span class="token property">padding</span><span class="token punctuation">:</span> 0 10px<span class="token punctuation">;</span>
    <span class="token property">line-height</span><span class="token punctuation">:</span> 32px<span class="token selector">;
    ::v-deep .van-field__left-icon .van-icon</span> <span class="token punctuation">{</span>
      <span class="token property">color</span><span class="token punctuation">:</span> #ccc<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token selector">&gt; .send</span> <span class="token punctuation">{</span>
    <span class="token property">margin-left</span><span class="token punctuation">:</span> 10px<span class="token punctuation">;</span>
    <span class="token property">font-size</span><span class="token punctuation">:</span> 14px<span class="token punctuation">;</span>
    <span class="token property">color</span><span class="token punctuation">:</span> #999<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><h3 id="_11-小智同学-认识websocket"><a href="#_11-小智同学-认识websocket" class="header-anchor">#</a> 11-小智同学-认识websocket</h3> <blockquote><p>目的：认识websocket https://websocket.org/</p></blockquote> <p>什么是 websocket ?</p> <ul><li>是一种网络通信协议，和 HTTP 协议 一样。</li></ul> <p>为什么需要websocket ?</p> <ul><li>因为 HTTP 协议有一个缺陷：通信只能由客户端发起。</li></ul> <p>理解 websokect  通讯过程</p> <p><img src="https://www.ruanyifeng.com/blogimg/asset/2017/bg2017051502.png" alt="img"></p> <p>了解 websocket 代码含义 <code>https://websocket.org/echo.html</code> <code>http://jsbin.com/muqamiqimu/edit?js,console</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 创建ws实例，建立连接</span>
<span class="token keyword">var</span> ws <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebSocket</span><span class="token punctuation">(</span><span class="token string">&quot;wss://echo.websocket.org&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 连接成功事件</span>
ws<span class="token punctuation">.</span><span class="token function-variable function">onopen</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Connection open ...&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 发送消息</span>
  ws<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token string">&quot;Hello WebSockets!&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// 接受消息事件</span>
ws<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">&quot;Received Message: &quot;</span> <span class="token operator">+</span> evt<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// 关闭连接  </span>
  ws<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// 关闭连接事件</span>
ws<span class="token punctuation">.</span><span class="token function-variable function">onclose</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">evt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Connection closed.&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>      
</code></pre></div><p>我们项目中使用 socket.io-client 来实现客户端代码，它是基于 websocket 的库。</p> <h3 id="_12-小智同学-完成聊天"><a href="#_12-小智同学-完成聊天" class="header-anchor">#</a> 12-小智同学-完成聊天</h3> <blockquote><p>目标：使用socket.io-client完成聊天</p></blockquote> <p>大致步骤：</p> <ul><li>先了解下socket.io-client的使用</li> <li>在组件中实现聊天</li></ul> <p>落地代码：</p> <p>1） 先了解下socket.io-client的使用</p> <ul><li>仓库地址 https://github.com/socketio/socket.io-client</li> <li>官方文档 https://socket.io/   https://socketio.bootcss.com/docs/</li> <li>安装 <code>npm i socket.io-client</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> socketIO <span class="token keyword">from</span> <span class="token string">'socket.io-client'</span>
<span class="token keyword">const</span> io <span class="token operator">=</span> <span class="token function">socketIO</span><span class="token punctuation">(</span><span class="token string">'http:localhost:8080'</span><span class="token punctuation">)</span>
<span class="token comment">// 建立连接</span>
io<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'connect'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span> 
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'建立连接'</span><span class="token punctuation">)</span> 
  <span class="token comment">// 发送消息  </span>
  io<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'message'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>msg<span class="token operator">:</span><span class="token string">'你好'</span><span class="token punctuation">}</span><span class="token punctuation">)</span>  
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// 接受消息：data 是后台发的数据</span>
io<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'message'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'收到消息'</span><span class="token punctuation">)</span>
  <span class="token comment">// 关闭连接</span>
  io<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>2） 在组件中实现聊天</p> <ul><li>完成列表渲染</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> data () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     myAvatar: '',
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      list: [
</span><span class="token prefix inserted">+</span><span class="token line">         { name: 'xz', msg: '我是小智同学，需要什么帮助吗？' },
</span><span class="token prefix inserted">+</span><span class="token line">         { name: 'my', msg: '报名前端' }
</span><span class="token prefix inserted">+</span><span class="token line">      ],
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     value: ''
</span><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span></span></code></pre></div><div class="language-vue extra-class"><pre class="language-vue"><code>    <span class="token comment">&lt;!-- 聊天列表 --&gt;</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-list<span class="token punctuation">&quot;</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>list<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-item<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>(item,i) in list<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>i<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">:class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>{left:item.name===<span class="token punctuation">'</span>xz<span class="token punctuation">'</span>,right:item.name===<span class="token punctuation">'</span>my<span class="token punctuation">'</span>}<span class="token punctuation">&quot;</span></span>
      <span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>geek-icon</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.name===<span class="token punctuation">'</span>xz<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>xiaozhi<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>chat-pao<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{item.msg}}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-image</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>item.name===<span class="token punctuation">'</span>my<span class="token punctuation">'</span><span class="token punctuation">&quot;</span></span> <span class="token attr-name">fit</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>cover<span class="token punctuation">&quot;</span></span> <span class="token attr-name">round</span> <span class="token attr-name">:src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>myAvatar<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><ul><li>开始聊天</li></ul> <div class="language-vue extra-class"><pre class="language-vue"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>send<span class="token punctuation">&quot;</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>send()<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>发送<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> getUserProfile <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
<span class="token keyword">import</span> soekctIO <span class="token keyword">from</span> <span class="token string">'socket.io-client'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> baseURL <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">'UserChatPage'</span><span class="token punctuation">,</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      myAvatar<span class="token operator">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
      list<span class="token operator">:</span> <span class="token punctuation">[</span>
        <span class="token comment">// { name: 'xz', msg: '我是小智同学，需要什么帮助吗？' },</span>
        <span class="token comment">// { name: 'my', msg: '我要学前端' }</span>
      <span class="token punctuation">]</span><span class="token punctuation">,</span>
      value<span class="token operator">:</span> <span class="token string">''</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token keyword">async</span> <span class="token function">created</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">[</span><span class="token punctuation">,</span> res<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getUserProfile</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>myAvatar <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>data<span class="token punctuation">.</span>photo
    <span class="token comment">// 1. 建立连接</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>io <span class="token operator">=</span> <span class="token function">soekctIO</span><span class="token punctuation">(</span>baseURL<span class="token punctuation">,</span> <span class="token punctuation">{</span>
      query<span class="token operator">:</span> <span class="token punctuation">{</span>
        token<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>$store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>token
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
      transports<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'websocket'</span><span class="token punctuation">]</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token comment">// 2. 连接成功</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>io<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'connect'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'xz'</span><span class="token punctuation">,</span> msg<span class="token operator">:</span> <span class="token string">'我是小智同学，需要什么帮助吗？'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token comment">// 3. 接收消息</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>io<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">'message'</span><span class="token punctuation">,</span> <span class="token parameter">data</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'xz'</span><span class="token punctuation">,</span> msg<span class="token operator">:</span> data<span class="token punctuation">.</span>msg <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token function">beforeDestroy</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 4. 关闭连接</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>io<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token function">send</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$toast</span><span class="token punctuation">(</span><span class="token string">'请输入内容'</span><span class="token punctuation">)</span>
      <span class="token comment">// 发送消息</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>io<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">'message'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> msg<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value<span class="token punctuation">,</span> timestamp<span class="token operator">:</span> Date<span class="token punctuation">.</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">'my'</span><span class="token punctuation">,</span> msg<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token punctuation">}</span><span class="token punctuation">)</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">''</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>3）滚动底部：</p> <p><code>$nextTick</code>  等DOM更新完毕执行下一件事情</p> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   // 4. 接收消息
</span><span class="token prefix unchanged"> </span><span class="token line">   this.io.on('message', data =&gt; {
</span><span class="token prefix unchanged"> </span><span class="token line">     this.list.push({ name: 'xz', msg: data.msg })
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      this.scrollBottom()
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   })
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> beforeDestroy () {
</span><span class="token prefix unchanged"> </span><span class="token line">   // 5. 断开连接
</span><span class="token prefix unchanged"> </span><span class="token line">   this.io.close()
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> methods: {
</span><span class="token prefix unchanged"> </span><span class="token line">   // 3. 发送消息
</span><span class="token prefix unchanged"> </span><span class="token line">   send () {
</span><span class="token prefix unchanged"> </span><span class="token line">     if (!this.value) return this.$toast('请输入内容')
</span><span class="token prefix unchanged"> </span><span class="token line">     // 发消息
</span><span class="token prefix unchanged"> </span><span class="token line">     this.io.emit('message', { msg: this.value, timestamp: Date.now() })
</span><span class="token prefix unchanged"> </span><span class="token line">     // 存聊天记录
</span><span class="token prefix unchanged"> </span><span class="token line">     this.list.push({ name: 'my', msg: this.value })
</span><span class="token prefix unchanged"> </span><span class="token line">     this.value = ''
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      this.scrollBottom()
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   },
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    scrollBottom () {
</span><span class="token prefix inserted">+</span><span class="token line">      this.$nextTick(() =&gt; {
</span><span class="token prefix inserted">+</span><span class="token line">        // 思路：滚动的距离 = 可滚动的高度 - 自身高度
</span><span class="token prefix inserted">+</span><span class="token line">        const scrollHeight = this.$refs.list.scrollHeight
</span><span class="token prefix inserted">+</span><span class="token line">        const offsetHeight = this.$refs.list.offsetHeight
</span><span class="token prefix inserted">+</span><span class="token line">        this.$refs.list.scrollTop = scrollHeight - offsetHeight
</span><span class="token prefix inserted">+</span><span class="token line">      })
</span><span class="token prefix inserted">+</span><span class="token line">    }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span></code></pre></div><h2 id="第九章-项目收尾"><a href="#第九章-项目收尾" class="header-anchor">#</a> 第九章：项目收尾</h2> <h3 id="_01-刷新token"><a href="#_01-刷新token" class="header-anchor">#</a> 01-刷新token</h3> <blockquote><p>目的：无感延长token有效期</p></blockquote> <p>大致步骤：</p> <ul><li>登录完毕后台返回：token  1-2小时  refresh_token  30天，利用它可以让登录延续30天。</li> <li>理解使用 refresh_token 过程
<ul><li>vuex 本地存储  需要记录  refresh_token</li> <li>当你发<strong>请求</strong>的时候出现401，响应拦截器中</li> <li>拿着refresh_token向后台获取新的有效的token</li> <li>把本地的token更新成新的token</li> <li>继续发送之前失败的 <strong>请求</strong>  需要返回promise</li> <li>如果你用 refresh_token 去获取token的时候失败了，无效了，去登录</li></ul></li></ul> <p>落地代码：</p> <ul><li>存储refresh_token <code>src/store/modules/user.js</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>// 用户模块共享数据管理
export default {
<span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> namespaced: true,
</span><span class="token prefix unchanged"> </span><span class="token line"> // 状态
</span><span class="token prefix unchanged"> </span><span class="token line"> state () {
</span><span class="token prefix unchanged"> </span><span class="token line">   return {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 令牌  初始化从本地获取
</span><span class="token prefix unchanged"> </span><span class="token line">     token: localStorage.getItem('geek-client-mobile-token'),
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">      refreshToken: localStorage.getItem('geek-client-mobile-refreshToken')
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> },
</span><span class="token prefix unchanged"> </span><span class="token line"> // 修改
</span><span class="token prefix unchanged"> </span><span class="token line"> mutations: {
</span><span class="token prefix unchanged"> </span><span class="token line">   setToken (state, token) {
</span><span class="token prefix unchanged"> </span><span class="token line">     // 1. 修改vuex的数据
</span><span class="token prefix unchanged"> </span><span class="token line">     state.token = token
</span><span class="token prefix unchanged"> </span><span class="token line">     // 2. 同步修改本地
</span><span class="token prefix unchanged"> </span><span class="token line">     localStorage.setItem('geek-client-mobile-token', token)
</span><span class="token prefix unchanged"> </span><span class="token line">   },
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    setRefreshToken (state, refreshToken) {
</span><span class="token prefix inserted">+</span><span class="token line">      // 1. 修改vuex的数据
</span><span class="token prefix inserted">+</span><span class="token line">      state.refreshToken = refreshToken
</span><span class="token prefix inserted">+</span><span class="token line">      // 2. 同步修改本地
</span><span class="token prefix inserted">+</span><span class="token line">      localStorage.setItem('geek-client-mobile-refreshToken', refreshToken)
</span><span class="token prefix inserted">+</span><span class="token line">    }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span>}

</code></pre></div><ul><li>刷新token的API  <code>src/api/user.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> request<span class="token punctuation">,</span> <span class="token punctuation">{</span> baseURL <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/utils/request'</span>
<span class="token keyword">import</span> axios <span class="token keyword">from</span> <span class="token string">'axios'</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/**
 * 刷新token
 * @param {String} refreshToken - 保存的refresh_token
 * @returns
 */</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">refreshTokenAPI</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">refreshToken</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    url<span class="token operator">:</span> baseURL <span class="token operator">+</span> <span class="token string">'v1_0/authorizations'</span><span class="token punctuation">,</span>
    method<span class="token operator">:</span> <span class="token string">'put'</span><span class="token punctuation">,</span>
    headers<span class="token operator">:</span> <span class="token punctuation">{</span>
      Authorization<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Bearer </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>refreshToken<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

</code></pre></div><ul><li>响应拦截器，调用API <code>src/utils/request.js</code></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> refreshTokenAPI <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@/api/user'</span>
</code></pre></div><div class="language-diff extra-class"><pre class="language-diff"><code>// 4. token失效处理
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">instance.interceptors.response.use(res =&gt; res, async err =&gt; {
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> // 1. 判断状态码401
</span><span class="token prefix unchanged"> </span><span class="token line"> // 2. 删除token
</span><span class="token prefix unchanged"> </span><span class="token line"> // 3. 跳转登录，当前路由的完整地址需要传递给登录页面。因为：将来登录完事需要回跳
</span><span class="token prefix unchanged"> </span><span class="token line"> if (err.response &amp;&amp; err.response.status === 401) {
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">    // ★1. 使用refresh_token更新token不能使用instance，请求拦截器中会覆盖请求头
</span><span class="token prefix inserted">+</span><span class="token line">    const [err2, res] = await to(refreshTokenAPI(store.state.user.refreshToken))
</span><span class="token prefix inserted">+</span><span class="token line">    // ★2. 刷新token失败
</span><span class="token prefix inserted">+</span><span class="token line">    if (err2) {
</span><span class="token prefix inserted">+</span><span class="token line">      store.commit('user/setToken', '')
</span><span class="token prefix inserted">+</span><span class="token line">      // 组件：this.$route.path 路径  fullPath 完整路径，带参数的
</span><span class="token prefix inserted">+</span><span class="token line">      // 通过 router实例 获取当前路由信息对象 currentRoute
</span><span class="token prefix inserted">+</span><span class="token line">      // 回跳地址：/order?id=100&amp;name=tom  ===&gt; 跳转登录地址  /login?returnUrl=/order?id=100&amp;name=tom
</span><span class="token prefix inserted">+</span><span class="token line">      // 地址可能回出现特殊字符 &amp; 需要转换成url编码 encodeURIComponent
</span><span class="token prefix inserted">+</span><span class="token line">      // 转义后 /login?returnUrl=%2Forder%3Fid%3D100%26name%3Dtom
</span><span class="token prefix inserted">+</span><span class="token line">      router.push('/login?returnUrl=' + encodeURIComponent(router.currentRoute.fullPath))
</span><span class="token prefix inserted">+</span><span class="token line">    } else {
</span><span class="token prefix inserted">+</span><span class="token line">      // ★3. 刷新token成功
</span><span class="token prefix inserted">+</span><span class="token line">      store.commit('user/setToken', res.data.data.token)
</span><span class="token prefix inserted">+</span><span class="token line">      // ★4. 继续发送失败的请求，需要成功
</span><span class="token prefix inserted">+</span><span class="token line">      // err.config 是之前失败的请求配置
</span><span class="token prefix inserted">+</span><span class="token line">      return instance(err.config)
</span><span class="token prefix inserted">+</span><span class="token line">    }
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> }
</span><span class="token prefix unchanged"> </span><span class="token line"> return Promise.reject(err)
</span></span>})
</code></pre></div><ul><li>推出登录 <code>src/views/user/profile/index.vue</code></li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">     }).then(() =&gt; {
</span><span class="token prefix unchanged"> </span><span class="token line">       // 确认后退出
</span><span class="token prefix unchanged"> </span><span class="token line">       this.$store.commit('user/setToken', '')
</span></span><span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">        this.$store.commit('user/setRefreshToken', '')
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line">       this.$router.push('/')
</span><span class="token prefix unchanged"> </span><span class="token line">     }).catch(e =&gt; {})
</span></span></code></pre></div><h3 id="_02-打包部署"><a href="#_02-打包部署" class="header-anchor">#</a> 02-打包部署</h3> <blockquote><p>目的：打包之后部署至服务器</p></blockquote> <p>大致步骤：</p> <ul><li>修改打包后资源引用为相对路径</li> <li>执行 npm run build 打包出资源</li> <li>上传到服务器，使用node托管</li></ul> <p>落地内容：</p> <ul><li>修改打包后资源引用为相对路径</li></ul> <div class="language-diff extra-class"><pre class="language-diff"><code>// vue-cli的配置文件
module.exports = {
<span class="token inserted-sign inserted"><span class="token prefix inserted">+</span><span class="token line">  publicPath: './',
</span></span><span class="token unchanged"><span class="token prefix unchanged"> </span><span class="token line"> css: {
</span><span class="token prefix unchanged"> </span><span class="token line">   loaderOptions: {
</span><span class="token prefix unchanged"> </span><span class="token line">     less: {
</span><span class="token prefix unchanged"> </span><span class="token line">       // less 的全局变量
</span><span class="token prefix unchanged"> </span><span class="token line">       globalVars: {
</span><span class="token prefix unchanged"> </span><span class="token line">         'geek-color': '#FC6627',
</span><span class="token prefix unchanged"> </span><span class="token line">         'geek-gray-color': '#F7F8FA'
</span><span class="token prefix unchanged"> </span><span class="token line">       }
</span><span class="token prefix unchanged"> </span><span class="token line">     }
</span><span class="token prefix unchanged"> </span><span class="token line">   }
</span><span class="token prefix unchanged"> </span><span class="token line"> }
</span></span>}
</code></pre></div><ul><li>执行 npm run build 打包出资源</li></ul> <p><img src="/document/assets/img/1627469626360.0d1c0165.png" alt="1627469626360"></p> <ul><li>上传到服务器，使用node托管
<ul><li>将来工作中一般只需要把你打包的资源给后台或者运维即可，托管的服务器也不一定是node。</li></ul></li></ul> <h3 id="_03-项目总结"><a href="#_03-项目总结" class="header-anchor">#</a> 03-项目总结</h3> <blockquote><p>目的：掌握项目技术解决方案，业务解决方案。</p></blockquote> <ul><li>能够使用vant组件库构建移动界面</li> <li>能够使用 postcss-px-to-viewport 完成移动端适配</li> <li>能够使用 命名视图 完成页面局部内容复用</li> <li>能够使用 svg 方式的多色字体图标</li> <li>能够封装 request 请求工具</li> <li>能够使用 await-to-js 处理await代码异常</li> <li>能够使用 token 完成用户鉴权</li> <li>能够实现 移动端 上拉加载下拉刷新效果</li> <li>能够实现 移动端 骨架效果</li> <li>能够使用 dayjs 处理时间</li> <li>能够使用 keep-alive 针对某组件缓存</li> <li>能够实现 列表滚动位置记忆功能</li> <li>能够使用 highlight.js 对富文本代码 高亮功能</li> <li>能够实现 本地与线上 频道管理</li> <li>能够实现 评论与回复 功能</li> <li>能够使用 socket.io-client 完成双向通讯</li> <li>能够掌握 用户无感 刷新token</li></ul></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"></div></div>
    <script src="/document/assets/js/app.9911b446.js" defer></script><script src="/document/assets/js/3.5cec4c48.js" defer></script><script src="/document/assets/js/4.9359f99f.js" defer></script>
  </body>
</html>
